---------------------
PatchSet 4 
Date: 2000/01/26 03:25:00
Author: hno
Branch: NLANR
Tag: s2_3_s1 
Log:
Imported Squid-2.3.STABLE1 sources

Members: 
	CONTRIBUTORS:1.1.1.2->1.1.1.3 
	CREDITS:1.1.1.2->1.1.1.3 
	ChangeLog:1.1.1.2->1.1.1.3 
	acconfig.h:1.1.1.2->1.1.1.3 
	configure:1.1.1.2->1.1.1.3 
	configure.in:1.1.1.2->1.1.1.3 
	makefile.in:1.1.1.2->1.1.1.3 
	auth_modules/LDAP/Makefile.in:1.1->1.1.1.1 
	auth_modules/LDAP/README:1.1->1.1.1.1 
	auth_modules/LDAP/squid_ldap_auth.c:1.1->1.1.1.1 
	auth_modules/MSNT/COPYING-2.0:1.1->1.1.1.1 
	auth_modules/MSNT/Makefile:1.1->1.1.1.1 
	auth_modules/MSNT/README:1.1->1.1.1.1 
	auth_modules/MSNT/byteorder.h:1.1->1.1.1.1 
	auth_modules/MSNT/md4.c:1.1->1.1.1.1 
	auth_modules/MSNT/msntauth-v1.0.lsm:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-common.h:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-error.h:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-io.c:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-io.h:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-priv.h:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-util.c:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb-util.h:1.1->1.1.1.1 
	auth_modules/MSNT/rfcnb.h:1.1->1.1.1.1 
	auth_modules/MSNT/session.c:1.1->1.1.1.1 
	auth_modules/MSNT/smbauth.c:1.1->1.1.1.1 
	auth_modules/MSNT/smbdes.c:1.1->1.1.1.1 
	auth_modules/MSNT/smbencrypt.c:1.1->1.1.1.1 
	auth_modules/MSNT/smblib-common.h:1.1->1.1.1.1 
	auth_modules/MSNT/smblib-priv.h:1.1->1.1.1.1 
	auth_modules/MSNT/smblib-util.c:1.1->1.1.1.1 
	auth_modules/MSNT/smblib.c:1.1->1.1.1.1 
	auth_modules/MSNT/smblib.h:1.1->1.1.1.1 
	auth_modules/MSNT/std-defines.h:1.1->1.1.1.1 
	auth_modules/MSNT/std-includes.h:1.1->1.1.1.1 
	auth_modules/MSNT/valid.c:1.1->1.1.1.1 
	auth_modules/MSNT/valid.h:1.1->1.1.1.1 
	auth_modules/PAM/Makefile.in:1.1->1.1.1.1 
	auth_modules/PAM/pam_auth.c:1.1->1.1.1.1 
	auth_modules/SMB/Changelog:1.1.1.1->1.1.1.2 
	auth_modules/SMB/Makefile.in:1.1->1.1.1.1 
	auth_modules/SMB/smb_auth.c:1.1.1.1->1.1.1.2 
	auth_modules/SMB/smb_auth.sh:1.1.1.1->1.1.1.2 
	auth_modules/getpwnam/Makefile.in:1.1.1.1->1.1.1.2 
	cfgaux/config.guess:1.1.1.2->1.1.1.3 
	cfgaux/config.sub:1.1.1.2->1.1.1.3 
	doc/debug-sections.txt:1.1.1.1->1.1.1.2 
	doc/draft-vixie-htcp-proto-04.txt:1.1->1.1.1.1 
	doc/Programming-Guide/prog-guide.sgml:1.1.1.1->1.1.1.2 
	errors/Makefile.in:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_CACHE_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_CACHE_MGR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_CANNOT_FORWARD:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_CONNECT_FAIL:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_DNS_FAIL:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FORWARDING_DENIED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_DISABLED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_FAILURE:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_PUT_CREATED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_PUT_ERROR:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_PUT_MODIFIED:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_INVALID_REQ:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_INVALID_URL:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_LIFETIME_EXP:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_NO_RELAY:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_ONLY_IF_CACHED_MISS:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_READ_ERROR:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_READ_TIMEOUT:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_SOCKET_FAILURE:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Bulgarian/ERR_UNSUP_REQ:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_URN_RESOLVE:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_WRITE_ERROR:1.1.1.1->1.1.1.2 
	errors/Bulgarian/ERR_ZERO_SIZE_OBJECT:1.1.1.1->1.1.1.2 
	errors/Bulgarian/README:1.1.1.1->1.1.1.2 
	errors/Bulgarian/generic:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_CACHE_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_CACHE_MGR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_CANNOT_FORWARD:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_CONNECT_FAIL:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_DNS_FAIL:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FORWARDING_DENIED:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_DISABLED:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_FAILURE:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_PUT_ERROR:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_INVALID_REQ:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_INVALID_URL:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_LIFETIME_EXP:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_NO_RELAY:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_ONLY_IF_CACHED_MISS:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_READ_ERROR:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_READ_TIMEOUT:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_SOCKET_FAILURE:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Czech/ERR_UNSUP_REQ:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_URN_RESOLVE:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_WRITE_ERROR:1.1.1.1->1.1.1.2 
	errors/Czech/ERR_ZERO_SIZE_OBJECT:1.1.1.1->1.1.1.2 
	errors/Czech/README:1.1.1.1->1.1.1.2 
	errors/Danish/ERR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Danish/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Danish/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Danish/ERR_CANNOT_FORWARD:1.1->1.1.1.1 
	errors/Danish/ERR_CLIENT_ABORT:1.1->1.1.1.1 
	errors/Danish/ERR_CONNECT_FAIL:1.1->1.1.1.1 
	errors/Danish/ERR_DNS_FAIL:1.1->1.1.1.1 
	errors/Danish/ERR_FORWARDING_DENIED:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_DISABLED:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_FAILURE:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_FORBIDDEN:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_NOT_FOUND:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Danish/ERR_FTP_UNAVAILABLE:1.1->1.1.1.1 
	errors/Danish/ERR_INVALID_REQ:1.1->1.1.1.1 
	errors/Danish/ERR_INVALID_URL:1.1->1.1.1.1 
	errors/Danish/ERR_LIFETIME_EXP:1.1->1.1.1.1 
	errors/Danish/ERR_NO_RELAY:1.1->1.1.1.1 
	errors/Danish/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Danish/ERR_READ_ERROR:1.1->1.1.1.1 
	errors/Danish/ERR_READ_TIMEOUT:1.1->1.1.1.1 
	errors/Danish/ERR_SHUTTING_DOWN:1.1->1.1.1.1 
	errors/Danish/ERR_SOCKET_FAILURE:1.1->1.1.1.1 
	errors/Danish/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Danish/ERR_UNSUP_REQ:1.1->1.1.1.1 
	errors/Danish/ERR_URN_RESOLVE:1.1->1.1.1.1 
	errors/Danish/ERR_WRITE_ERROR:1.1->1.1.1.1 
	errors/Danish/ERR_ZERO_SIZE_OBJECT:1.1->1.1.1.1 
	errors/Danish/README:1.1->1.1.1.1 
	errors/Danish/generic:1.1->1.1.1.1 
	errors/Dutch/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/English/ERR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/English/ERR_CANNOT_FORWARD:1.1.1.1->1.1.1.2 
	errors/English/ERR_CONNECT_FAIL:1.1.1.1->1.1.1.2 
	errors/English/ERR_DNS_FAIL:1.1.1.1->1.1.1.2 
	errors/English/ERR_FORWARDING_DENIED:1.1.1.1->1.1.1.2 
	errors/English/ERR_FTP_DISABLED:1.1.1.1->1.1.1.2 
	errors/English/ERR_FTP_FAILURE:1.1.1.2->1.1.1.3 
	errors/English/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/English/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/English/ERR_FTP_PUT_ERROR:1.1.1.1->1.1.1.2 
	errors/English/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/English/ERR_INVALID_REQ:1.1.1.1->1.1.1.2 
	errors/English/ERR_INVALID_URL:1.1.1.1->1.1.1.2 
	errors/English/ERR_LIFETIME_EXP:1.1.1.1->1.1.1.2 
	errors/English/ERR_NO_RELAY:1.1.1.1->1.1.1.2 
	errors/English/ERR_ONLY_IF_CACHED_MISS:1.1.1.1->1.1.1.2 
	errors/English/ERR_READ_ERROR:1.1.1.1->1.1.1.2 
	errors/English/ERR_READ_TIMEOUT:1.1.1.1->1.1.1.2 
	errors/English/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/English/ERR_SOCKET_FAILURE:1.1.1.1->1.1.1.2 
	errors/English/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/English/ERR_UNSUP_REQ:1.1.1.1->1.1.1.2 
	errors/English/ERR_URN_RESOLVE:1.1.1.1->1.1.1.2 
	errors/English/ERR_WRITE_ERROR:1.1.1.1->1.1.1.2 
	errors/English/ERR_ZERO_SIZE_OBJECT:1.1.1.1->1.1.1.2 
	errors/Estonian/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Finnish/ERR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Finnish/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Finnish/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Finnish/ERR_CANNOT_FORWARD:1.1->1.1.1.1 
	errors/Finnish/ERR_CLIENT_ABORT:1.1->1.1.1.1 
	errors/Finnish/ERR_CONNECT_FAIL:1.1->1.1.1.1 
	errors/Finnish/ERR_DNS_FAIL:1.1->1.1.1.1 
	errors/Finnish/ERR_FORWARDING_DENIED:1.1->1.1.1.1 
	errors/Finnish/ERR_FTP_DISABLED:1.1->1.1.1.1 
	errors/Finnish/ERR_FTP_FAILURE:1.1->1.1.1.1 
	errors/Finnish/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Finnish/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Finnish/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Finnish/ERR_INVALID_REQ:1.1->1.1.1.1 
	errors/Finnish/ERR_INVALID_URL:1.1->1.1.1.1 
	errors/Finnish/ERR_LIFETIME_EXP:1.1->1.1.1.1 
	errors/Finnish/ERR_NO_RELAY:1.1->1.1.1.1 
	errors/Finnish/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Finnish/ERR_READ_ERROR:1.1->1.1.1.1 
	errors/Finnish/ERR_READ_TIMEOUT:1.1->1.1.1.1 
	errors/Finnish/ERR_SOCKET_FAILURE:1.1->1.1.1.1 
	errors/Finnish/ERR_UNSUP_REQ:1.1->1.1.1.1 
	errors/Finnish/ERR_URN_RESOLVE:1.1->1.1.1.1 
	errors/Finnish/ERR_WRITE_ERROR:1.1->1.1.1.1 
	errors/Finnish/ERR_ZERO_SIZE_OBJECT:1.1->1.1.1.1 
	errors/Finnish/README:1.1->1.1.1.1 
	errors/Finnish/generic:1.1->1.1.1.1 
	errors/French/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/French/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/French/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/French/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/French/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/French/README:1.1.1.1->1.1.1.2 
	errors/German/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Hungarian/ERR_FTP_FAILURE:1.1.1.1->1.1.1.2 
	errors/Hungarian/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Hungarian/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Hungarian/ERR_FTP_PUT_ERROR:1.1.1.1->1.1.1.2 
	errors/Hungarian/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Hungarian/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Italian/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Italian/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Italian/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Italian/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/Italian/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Italian/README:1.1.1.1->1.1.1.2 
	errors/Japanese/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Korean/ERR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Korean/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Korean/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Korean/ERR_CANNOT_FORWARD:1.1->1.1.1.1 
	errors/Korean/ERR_CONNECT_FAIL:1.1->1.1.1.1 
	errors/Korean/ERR_DNS_FAIL:1.1->1.1.1.1 
	errors/Korean/ERR_FORWARDING_DENIED:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_DISABLED:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_FAILURE:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_FORBIDDEN:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_NOT_FOUND:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Korean/ERR_FTP_UNAVAILABLE:1.1->1.1.1.1 
	errors/Korean/ERR_INVALID_REQ:1.1->1.1.1.1 
	errors/Korean/ERR_INVALID_URL:1.1->1.1.1.1 
	errors/Korean/ERR_LIFETIME_EXP:1.1->1.1.1.1 
	errors/Korean/ERR_NO_RELAY:1.1->1.1.1.1 
	errors/Korean/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Korean/ERR_READ_ERROR:1.1->1.1.1.1 
	errors/Korean/ERR_READ_TIMEOUT:1.1->1.1.1.1 
	errors/Korean/ERR_SHUTTING_DOWN:1.1->1.1.1.1 
	errors/Korean/ERR_SOCKET_FAILURE:1.1->1.1.1.1 
	errors/Korean/ERR_UNSUP_REQ:1.1->1.1.1.1 
	errors/Korean/ERR_URN_RESOLVE:1.1->1.1.1.1 
	errors/Korean/ERR_WRITE_ERROR:1.1->1.1.1.1 
	errors/Korean/ERR_ZERO_SIZE_OBJECT:1.1->1.1.1.1 
	errors/Korean/README:1.1->1.1.1.1 
	errors/Korean/generic:1.1->1.1.1.1 
	errors/Polish/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Portuguese/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Romanian/ERR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Romanian/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Romanian/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Romanian/ERR_CANNOT_FORWARD:1.1->1.1.1.1 
	errors/Romanian/ERR_CONNECT_FAIL:1.1->1.1.1.1 
	errors/Romanian/ERR_DNS_FAIL:1.1->1.1.1.1 
	errors/Romanian/ERR_FORWARDING_DENIED:1.1->1.1.1.1 
	errors/Romanian/ERR_FTP_DISABLED:1.1->1.1.1.1 
	errors/Romanian/ERR_FTP_FAILURE:1.1->1.1.1.1 
	errors/Romanian/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Romanian/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Romanian/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Romanian/ERR_INVALID_REQ:1.1->1.1.1.1 
	errors/Romanian/ERR_INVALID_URL:1.1->1.1.1.1 
	errors/Romanian/ERR_LIFETIME_EXP:1.1->1.1.1.1 
	errors/Romanian/ERR_NO_RELAY:1.1->1.1.1.1 
	errors/Romanian/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Romanian/ERR_READ_ERROR:1.1->1.1.1.1 
	errors/Romanian/ERR_READ_TIMEOUT:1.1->1.1.1.1 
	errors/Romanian/ERR_SHUTTING_DOWN:1.1->1.1.1.1 
	errors/Romanian/ERR_SOCKET_FAILURE:1.1->1.1.1.1 
	errors/Romanian/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Romanian/ERR_UNSUP_REQ:1.1->1.1.1.1 
	errors/Romanian/ERR_URN_RESOLVE:1.1->1.1.1.1 
	errors/Romanian/ERR_WRITE_ERROR:1.1->1.1.1.1 
	errors/Romanian/ERR_ZERO_SIZE_OBJECT:1.1->1.1.1.1 
	errors/Romanian/README:1.1->1.1.1.1 
	errors/Russian-1251/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Russian-koi8-r/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Slovak/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Slovak/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Slovak/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Slovak/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/Slovak/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Spanish/ERR_ACCESS_DENIED:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Spanish/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Spanish/ERR_CANNOT_FORWARD:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_CONNECT_FAIL:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_DNS_FAIL:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FORWARDING_DENIED:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FTP_DISABLED:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FTP_FAILURE:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FTP_FORBIDDEN:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FTP_NOT_FOUND:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Spanish/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Spanish/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Spanish/ERR_FTP_UNAVAILABLE:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_INVALID_REQ:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_INVALID_URL:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_LIFETIME_EXP:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_NO_RELAY:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Spanish/ERR_READ_ERROR:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_READ_TIMEOUT:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_SHUTTING_DOWN:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_SOCKET_FAILURE:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Spanish/ERR_UNSUP_REQ:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_URN_RESOLVE:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_WRITE_ERROR:1.1.1.1->1.1.1.2 
	errors/Spanish/ERR_ZERO_SIZE_OBJECT:1.1.1.1->1.1.1.2 
	errors/Spanish/README:1.1.1.1->1.1.1.2 
	errors/Swedish/ERR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Swedish/ERR_CACHE_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Swedish/ERR_CACHE_MGR_ACCESS_DENIED:1.1->1.1.1.1 
	errors/Swedish/ERR_CANNOT_FORWARD:1.1->1.1.1.1 
	errors/Swedish/ERR_CONNECT_FAIL:1.1->1.1.1.1 
	errors/Swedish/ERR_DNS_FAIL:1.1->1.1.1.1 
	errors/Swedish/ERR_FORWARDING_DENIED:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_DISABLED:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_FAILURE:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_FORBIDDEN:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_NOT_FOUND:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_PUT_CREATED:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_PUT_ERROR:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_PUT_MODIFIED:1.1->1.1.1.1 
	errors/Swedish/ERR_FTP_UNAVAILABLE:1.1->1.1.1.1 
	errors/Swedish/ERR_INVALID_REQ:1.1->1.1.1.1 
	errors/Swedish/ERR_INVALID_URL:1.1->1.1.1.1 
	errors/Swedish/ERR_LIFETIME_EXP:1.1->1.1.1.1 
	errors/Swedish/ERR_NO_RELAY:1.1->1.1.1.1 
	errors/Swedish/ERR_ONLY_IF_CACHED_MISS:1.1->1.1.1.1 
	errors/Swedish/ERR_READ_ERROR:1.1->1.1.1.1 
	errors/Swedish/ERR_READ_TIMEOUT:1.1->1.1.1.1 
	errors/Swedish/ERR_SHUTTING_DOWN:1.1->1.1.1.1 
	errors/Swedish/ERR_SOCKET_FAILURE:1.1->1.1.1.1 
	errors/Swedish/ERR_UNSUP_REQ:1.1->1.1.1.1 
	errors/Swedish/ERR_URN_RESOLVE:1.1->1.1.1.1 
	errors/Swedish/ERR_WRITE_ERROR:1.1->1.1.1.1 
	errors/Swedish/ERR_ZERO_SIZE_OBJECT:1.1->1.1.1.1 
	errors/Swedish/README:1.1->1.1.1.1 
	errors/Swedish/generic:1.1->1.1.1.1 
	errors/Traditional_Chinese/ERR_TOO_BIG:1.1->1.1.1.1 
	errors/Turkish/ERR_TOO_BIG:1.1->1.1.1.1 
	icons/Makefile.in:1.1.1.2->1.1.1.3 
	include/autoconf.h.in:1.1.1.2->1.1.1.3 
	include/cache_snmp.h:1.1.1.2->1.1.1.3 
	include/config.h.in:1.1.1.2->1.1.1.3 
	include/heap.h:1.1->1.1.1.1 
	include/rfc1035.h:1.1->1.1.1.1 
	include/snmp_vars.h:1.1.1.1->1.1.1.2 
	include/splay.h:1.1.1.1->1.1.1.2 
	include/util.h:1.1.1.2->1.1.1.3 
	include/version.h:1.1.1.2->1.1.1.3 
	lib/Array.c:1.1.1.1->1.1.1.2 
	lib/Makefile.in:1.1.1.1->1.1.1.2 
	lib/Stack.c:1.1.1.1->1.1.1.2 
	lib/drand48.c:1.1.1.1->1.1.1.2 
	lib/hash.c:1.1.1.2->1.1.1.3 
	lib/heap.c:1.1->1.1.1.1 
	lib/md5.c:1.1.1.1->1.1.1.2 
	lib/rfc1035.c:1.1->1.1.1.1 
	lib/rfc1123.c:1.1.1.2->1.1.1.3 
	lib/rfc1738.c:1.1.1.1->1.1.1.2 
	lib/safe_inet_addr.c:1.1.1.2->1.1.1.3 
	lib/snprintf.c:1.1.1.2->1.1.1.3 
	lib/splay.c:1.1.1.1->1.1.1.2 
	lib/stub_memaccount.c:1.1.1.1->1.1.1.2 
	lib/util.c:1.1.1.2->1.1.1.3 
	scripts/access-log-matrix.pl:1.1.1.1->1.1.1.2 
	snmplib/snmp_vars.c:1.1.1.1->1.1.1.2 
	src/HttpHdrCc.c:1.1.1.2->1.1.1.3 
	src/HttpHdrContRange.c:1.1.1.2->1.1.1.3 
	src/HttpHdrExtField.c:1.1.1.2->1.1.1.3 
	src/HttpHdrRange.c:1.1.1.2->1.1.1.3 
	src/HttpHeader.c:1.1.1.2->1.1.1.3 
	src/HttpHeaderTools.c:1.1.1.2->1.1.1.3 
	src/HttpReply.c:1.1.1.2->1.1.1.3 
	src/HttpRequest.c:1.1.1.2->1.1.1.3 
	src/HttpStatusLine.c:1.1.1.2->1.1.1.3 
	src/Makefile.in:1.1.1.2->1.1.1.3 
	src/MemPool.c:1.1.1.2->1.1.1.3 
	src/access_log.c:1.1.1.2->1.1.1.3 
	src/acl.c:1.1.1.2->1.1.1.3 
	src/aiops.c:1.1.1.2->1.1.1.3 
	src/asn.c:1.1.1.2->1.1.1.3 
	src/async_io.c:1.1.1.2->1.1.1.3 
	src/authenticate.c:1.1.1.2->1.1.1.3 
	src/cache_cf.c:1.1.1.2->1.1.1.3 
	src/cachemgr.c:1.1.1.2->1.1.1.3 
	src/cf.data.pre:1.1.1.2->1.1.1.3 
	src/cf_gen.c:1.1.1.2->1.1.1.3 
	src/client.c:1.1.1.2->1.1.1.3 
	src/client_db.c:1.1.1.2->1.1.1.3 
	src/client_side.c:1.1.1.2->1.1.1.3 
	src/comm.c:1.1.1.2->1.1.1.3 
	src/comm_select.c:1.1.1.2->1.1.1.3 
	src/debug.c:1.1.1.2->1.1.1.3 
	src/defines.h:1.1.1.2->1.1.1.3 
	src/delay_pools.c:1.1.1.2->1.1.1.3 
	src/disk.c:1.1.1.2->1.1.1.3 
	src/dns.c:1.1.1.2->1.1.1.3 
	src/dns_internal.c:1.1->1.1.1.1 
	src/dnsserver.c:1.1.1.2->1.1.1.3 
	src/enums.h:1.1.1.2->1.1.1.3 
	src/errorpage.c:1.1.1.2->1.1.1.3 
	src/event.c:1.1.1.2->1.1.1.3 
	src/fd.c:1.1.1.2->1.1.1.3 
	src/filemap.c:1.1.1.1->1.1.1.2 
	src/forward.c:1.1.1.2->1.1.1.3 
	src/fqdncache.c:1.1.1.2->1.1.1.3 
	src/ftp.c:1.1.1.2->1.1.1.3 
	src/globals.h:1.1.1.2->1.1.1.3 
	src/gopher.c:1.1.1.2->1.1.1.3 
	src/helper.c:1.1.1.2->1.1.1.3 
	src/htcp.c:1.1.1.1->1.1.1.2 
	src/http.c:1.1.1.2->1.1.1.3 
	src/icp_v2.c:1.1.1.2->1.1.1.3 
	src/icp_v3.c:1.1.1.2->1.1.1.3 
	src/ident.c:1.1.1.2->1.1.1.3 
	src/internal.c:1.1.1.2->1.1.1.3 
	src/ipc.c:1.1.1.2->1.1.1.3 
	src/ipcache.c:1.1.1.2->1.1.1.3 
	src/main.c:1.1.1.2->1.1.1.3 
	src/mem.c:1.1.1.2->1.1.1.3 
	src/mib.txt:1.1.1.2->1.1.1.3 
	src/mime.c:1.1.1.2->1.1.1.3 
	src/mime.conf:1.1.1.2->1.1.1.3 
	src/neighbors.c:1.1.1.2->1.1.1.3 
	src/net_db.c:1.1.1.2->1.1.1.3 
	src/peer_digest.c:1.1.1.2->1.1.1.3 
	src/peer_select.c:1.1.1.2->1.1.1.3 
	src/pinger.c:1.1.1.2->1.1.1.3 
	src/protos.h:1.1.1.2->1.1.1.3 
	src/pump.c:1.1.1.2->1.1.1.3 
	src/redirect.c:1.1.1.2->1.1.1.3 
	src/refresh.c:1.1.1.2->1.1.1.3 
	src/send-announce.c:1.1.1.2->1.1.1.3 
	src/snmp_agent.c:1.1.1.2->1.1.1.3 
	src/snmp_core.c:1.1.1.2->1.1.1.3 
	src/squid.h:1.1.1.2->1.1.1.3 
	src/ssl.c:1.1.1.2->1.1.1.3 
	src/stat.c:1.1.1.2->1.1.1.3 
	src/store.c:1.1.1.2->1.1.1.3 
	src/store_client.c:1.1.1.2->1.1.1.3 
	src/store_digest.c:1.1.1.2->1.1.1.3 
	src/store_dir.c:1.1.1.2->1.1.1.3 
	src/store_dir_ufs.c:1.1->1.1.1.1 
	src/store_heap_replacement.c:1.1->1.1.1.1 
	src/store_io.c:1.1->1.1.1.1 
	src/store_io_asyncufs.c:1.1->1.1.1.1 
	src/store_io_ufs.c:1.1->1.1.1.1 
	src/store_key_md5.c:1.1.1.2->1.1.1.3 
	src/store_log.c:1.1.1.1->1.1.1.2 
	src/store_rebuild.c:1.1.1.2->1.1.1.3 
	src/store_swapin.c:1.1.1.2->1.1.1.3 
	src/store_swapmeta.c:1.1.1.1->1.1.1.2 
	src/store_swapout.c:1.1.1.2->1.1.1.3 
	src/structs.h:1.1.1.2->1.1.1.3 
	src/tools.c:1.1.1.2->1.1.1.3 
	src/typedefs.h:1.1.1.2->1.1.1.3 
	src/unlinkd.c:1.1.1.2->1.1.1.3 
	src/url.c:1.1.1.2->1.1.1.3 
	src/urn.c:1.1.1.2->1.1.1.3 
	src/useragent.c:1.1.1.2->1.1.1.3 
	src/wccp.c:1.1->1.1.1.1 
	test-suite/tcp-banger2.c:1.1.1.2->1.1.1.3 

Index: squid/CONTRIBUTORS
===================================================================
RCS file: /cvsroot/squid-sf//squid/CONTRIBUTORS,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/CONTRIBUTORS	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/CONTRIBUTORS	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -69,6 +69,7 @@
 	Michael Lupp <mike@nemesis.saar.de>
 	Niall Doherty <ndoherty@eei.ericsson.se>
 	Pedro Ribeiro <pribeiro@isel.pt>
+	John Dilley <jad@hpl.hp.com>
 
 Development of this caching software is funded by the National Science
 Foundation (grants NCR-9616602 and NCR-9521745).  Paid staff members on
Index: squid/CREDITS
===================================================================
RCS file: /cvsroot/squid-sf//squid/CREDITS,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/CREDITS	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/CREDITS	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,4 +1,4 @@
-$Id: CREDITS,v 1.1.1.2 2000/01/26 03:23:09 hno Exp $
+$Id: CREDITS,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
 
 ==============================================================================
 
Index: squid/ChangeLog
===================================================================
RCS file: /cvsroot/squid-sf//squid/ChangeLog,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/ChangeLog	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/ChangeLog	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,10 +1,242 @@
+Changes to Squid-2.3.STABLE1 (Jan 9, 2000):
+
+	- Updated PAM authentication module from Henrik Nordstrom.
+	- Updated Bulgarian error messages from Svetlin Simeonov.
+	- Changed ACL routines so that User-Agent (browser) string
+	  is always taken from compiled HTTP request headers
+	  instead of passed as an argument to aclCreateChecklist.
+	- Added a 'strip' option to the 'uri_whitesace' configuration
+	  directive and made it the default behavior.  Whitespace
+	  found in URI's is now stripped out by default.
+	- Added chroot feature.  The 'chroot_dir' config option enables
+	  it and specifies the directory.
+	- Changed clientBuildReplyHeader so that the Age header is
+	  added only for cache hits, and only when we can calculate
+	  a valid, positive age value.
+	- Changed clientWriteComplete and clientGotNotEnough so
+	  that they keep persistent connections open for more types
+	  of replies that don't have bodies.
+	- Changed filemap.c routines to dynamically grow filemap
+	  space as needed.
+	- Added a hack to ftp.c to deal with ftp.netscape.com, which
+	  sometimes doesn't acknowledge PASV commands.
+	- Fixed FTP bug with ftpScheduleReadControlReply; there
+	  was not always a timeout handler on the control socket
+	  after the transfer completed.
+	- Fixed FTP filedescriptor leak from invalid PASV replies.
+	- Changed httpBuildRequestHeader so that it doesn't
+	  copy the Host header from the client request.  Instead
+	  we should generate our own Host header which is known
+	  to be correct.
+	- Changed storeTimestampsSet to adjust entry->timestamp
+	  if the response includes an Age header.
+	- Removed size limit from storeKeyHashBuckets.
+	- Changed fwdConnectStart from a "heavy" to a "light" event.
+	- Fixed an 'anonymize_headers' bug that affects unknown
+	  HTTP headers.  With the bug, if you list a header that
+	  Squid doesn't know about (such as "Charset"), it would
+	  add HDR_OTHER to the allow/deny mask.  This caused all
+	  unknown headers to be allowed or denied (depending on
+	  the scheme you use).  Now, with the bug fixed, an unknown
+	  header in the 'anonymize_headers' list is simply ignored.
+
+Changes to Squid-2.3.DEVEL3 ():
+
+	- Added MSNT auth module from Antonino Iannella.
+	- Added --enable-underscores configure option.  This allows
+	  Squid to accept hostnames with underscores in them.  Your
+	  DNS resolver may still complain about them, however.
+	- Added --heap-replacement configure option.  This enables
+	  the alternative cache replacement policies, such as
+	  GDSF, and LFUDA.
+	- WCCP establishes and registers with the router faster.	
+	- Added 'maxconn' acl type to limit the number of established
+	  connections from a single client IP address.  Submitted
+	  by Vadim Kolontsov.
+	- Close FTP data socket as soon as transfer completes
+	  (Alexander V. Lukyanov).
+	- Fixed ftpReadPass() to not clobber ctrl.message when
+	  the PASS command fails.
+	- Added a redirect.c patch so squidGuard is able to do
+	  per-user access control (Antony T Curtis).
+	- discard the pumpMethod() function, and instead use the
+	  fact that the request has a request entity (content-length
+	  present) (Henrik).
+	- Reload the MIME icons at reconfigure time (Radu Greab).
+	- Updated Richard Huveneers' SMB authentication module to
+	  his version 0.05 package.
+	- Fixed lib/heap.c::heap_delete() bug when deleting the
+	  last node.
+	- Fixed an integer conversion bug in
+	  lib/rfc1035.c::rfc1035AnswersUnpack().
+	- Fixed lib/rfc1738 routines to encode reserved characters,
+	  in addition to encoding the unsafe characters (Henrik).
+	- Changed the interface for splay compare and "walk"
+	  functions to take a void pointer, instead of a splayNode
+	  pointer (Henrik).
+	- Changed numerous HTTP parsing routines to use ssize_t
+	  instead of size_t.  This was done because size_t may be
+	  signed or unsigned.  When it is unsigned, gcc emits
+	  numerous "comparison is always true" warnings.  At least
+	  we know ssize_t is always signed.
+	- Fixed src/HttpHeaderTools::httpHeaderHasConnDir() and
+	  friends so that it properly handles multi-value lists.
+	- Added an "end" (ssize_t) parameter to
+	  src/HttpReply::httpReplyParse() so that we know exactly
+	  where to terminate the header buffer.
+	- Changed src/access_log.c::log_quote() so that it only
+	  encodes whitespace characters, and not all URL-special
+	  characters (Henrik).
+	- Added local port ACL type ("myport") (Henrik).
+	- Added maximum number of connections per client ("maxconn")
+	  as an ACL type.
+	- Fixed proxy authentication username/password parsing to
+	  be more robust (Henrik).
+	- Fixed ACL domain/host and domain/domain comparison
+	  functions yet again.  Eliminated duplicate code so that
+	  only src/url.c::matchDomainName() contains this mysterious
+	  code.
+	- Changed the 'http_port' option to accept an IP address
+	  or hostname as well (Henrik).
+	- Removed 'tcp_incoming_addr' option.
+	- Added an access control list for the redirector
+	  ('redirector_access').  Requests which match are sent to
+	  the redirector.  All requests. are redirected by default.
+	- Added the 'authenticate_ip_ttl' option.  It specifies
+	  how long a valid proxy authentication credential is
+	  bound to a specific address.
+	- Added 280, 488, 591, and 777 to "Safe_ports" ACL.
+	- Removed the unused and highly questionable 'forward_snmpd_port'
+	  option.
+	- Added an option to accept DNS messages from unknown nameservers.
+	  This may be necessary if replies come from a different address
+	  than queries are sent to.
+	- Added #includes for IP Filter files in netinet directory.
+	- Fixed a bug with retrying forwarded IMS requests (Henrik).
+	- Fixed a bug in src/client_side.c::clientInterpretRequestHeaders()
+	  where we were checking a cache-control bit before getting the
+	  mask from the HTTP headers (pallo@initio.no).
+	- Fixed a bug with "no_cache" access list.  If not defined,
+	  everything was uncachable by default.
+	- Fixed a bug with timed-out client-side HTTP connections.
+	  We didn't cancel the read handler, which could lead to 
+	  "rwstate != NULL" warnings.
+	- Changed comm_open() to only call fdAdjustReserved() for
+	  specific errors (ENFILE, EMFILE);
+	- Fixed NULL pointer bug in idnsParseResolvConf().
+	- Split CACHE_DIGEST_HIT into CD_PARENT_HIT and CD_SIBLING_HIT.
+	- Added DELETE request method.
+	- Added RFC 2518 HTTP status codes.
+	- Fixed handling of URL passwords when we need to rewrite a
+	  BASE HREF URL (Henrik).
+	- Fixed a bug with FTP requests where a request gets aborted,
+	  but we try to complete it anyway.  It would result in a
+	  "store_status != STORE_PENDING" assertion.  The solution
+	  is to check for ENTRY_ABORTED before reading from
+	  the control channel too.
+	- Changed FTP to retry a request if Squid fails to establish
+	  a PASV data connection (Henrik).
+	- Fixed numerous HTCP memory leaks and an uninitialized memory
+	  bug.
+	- Changed httpMaybeRemovePublic() with RFC 2518 and 2616 in
+	  mind (Henrik).
+	- Minor fixes for Rhapsody systems.
+	- Define _XOPEN_SOURCE_EXTENDED in squid.h so that AIX systems
+	  don't include varargs.h.
+	- Changed src/store_client.c::storeClientType() so that
+	  an entry can have more than one STORE_MEM_CLIENT.
+	- Changed src/store_client.c::storeClientReadHeader()
+	  to check swapfile metadata (Henrik).
+	- Changed src/url.c::urlCheckRequest() to return FALSE for
+	  any "https://" URL.  These should always be CONNECT
+	  instead.  If Squid gets an "https://" URL, it is a browser
+	  bug.
+	- Added numerous squid.conf options for controlling cache
+	  digests.   Previously these were hard-coded in
+	  src/store_digest.c.  (Martin Hamilton)
+	- Added 'cache_peer' option called 'digest-url' that
+	  lets you specify the URL for a peer's digest.
+	  (Martin Hamilton)
+	- Added DELAY_POOLS hacks to scan "slow" connections in
+	  a random order (David Luyer).
+	- ARP_ACL fixes from Damien Miller.  Linux 2.2.x uses a
+	  per-interface arp/neighbour cache, whereas 2.0.x uses a
+	  unified cache. Under 2.2.x you are required to specify
+	  a interface name when looking up ARP table entries with
+	  SIOCGARP.
+	- If the process umask is not set (i.e. 0), then Squid
+	  changes it to 007.
+
+Changes to Squid-2.3.DEVEL2 ():
+
+	- Added --enable-truncate configure option.
+	- Updated Czech error messages ()
+	- Updated French error messages ()
+	- Updated Spanish error messages ()
+	- Added xrename() function for better debugging.
+	- Disallow empty ("") password in aclDecodeProxyAuth()
+	  (BoB Miorelli).
+	- Fixed ACL SPLAY subdomain detection (again).
+	- Increased default 'request_body_max_size' from 100KB
+	  to 1MB in cf.data.pre.
+	- Added 'content_length' member to request_t structure
+	  so we don't have to use httpHdrGetInt() so often.
+	- Fixed repeatedly calling memDataInit() for every reconfigure.
+	- Cleaned up the case when fwdDispatch() cannot forward a
+	  request.  Error messages used to report "[no URL]".
+	- Added a check to return specific error messages for a
+	  "store_digest" request when the digest entry doesn't exist
+	  and we reach internalStart().
+	- Changed the interface of storeSwapInStart() to avoid a bug
+	  where we closed "sc->swapin_sio" but couldn't set the
+	  pointer to NULL.
+	- Changed storeDirClean() so that the rate it gets called
+	  depends on the number of objects deleted.
+	- Some WCCP fixes.
+	- Added 'hostname_aliases' option to detect internal requests
+	  (cache digests) when a cache has more than one hostname
+	  in use.
+	- Async I/O NUMTHREADS now configurable with --enable-async-io=N
+	  (Henrik Nordstrom).
+	- Added queue length to async I/O cachemgr stats (Henrik Nordstrom).
+	- Added OPTIONS request method.
+
+Changes to Squid-2.3.DEVEL1 ():
+
+	- Added WCCP support.  This adds the 'wccp_router' squid.conf
+	  option.
+	- Added internal DNS queries; Most installations can run
+	  without the external dnsserver processes.
+	- Rewrote much of the code that stores cache objects on
+	  disk.  Developed a programming interface that should
+	  allow new storage systems to be added easily.  This still
+	  is pretty ugly and needs a lot of work, however.
+	- Replaced async_io.c "tags" with callback data locks.
+	  This probably breaks async IO in a bad way.
+	- Tried to write an Async IO disk storage module.
+	- Added code to replace the StoreEntry linked list with a
+	  heap structure.  This allows for different replacement
+	  algorithms, instead of being stuck with LRU.  This adds
+	  the 'replacement_policy' squid.conf option. (John Dilley
+	  et al).
+	- Fixed HTCP queries by actually checking for freshness
+	  based on the HTCP header fields.
+	- Fixed passing of redirector command line arguments.
+	- Added 'request_header_max_size' squid.conf option.
+	- Added 'request_body_max_size' squid.conf option.
+	- Added 'reply_body_max_size' squid.conf option.
+	- Added 'peer_connect_timeout' squid.conf option.
+	- Added 'redirector_bypass' squid.conf option.
+	- Added RFC 2518 (WEBDAV) request methods.
+	
+
 Changes to Squid-2.2 (April 19, 1999):
 
 	- Removed all SNMP specific ACL code
 	  SNMP now uses generic squid ACL's
-	- Removed view-based access control
+	- Removed view-based access crontrol
 	- Cleaned up and simplified SNMP section of squid.conf
-	- Changed the SNMP code to use a tree structure.
+	- Changed the SNMP code to use a tree stucture.
 	- Added objects to MIB:	
 		Request Hit Ratio's
 		Byte Hit Ratio's
@@ -61,7 +293,7 @@
 		- The 'ident_lookup on|off' option has been replaced with
 		  an access list, so you can do lookups only for some
 		  client addresses.
-		- Added an 'ident_timeout' option to specify the amount
+		- Added an 'ident_timeout' option to specifiy the amount
 		  of time to wait for an ident lookup.
 	- Added a (local) hit rate to mempool metering.
 	- FTP Restarts (REST command) is now supported.
@@ -101,7 +333,7 @@
 		  as a percentage of the maximum for the pool in
 		  question (used to be all set to 1 second worth
 		  of traffic).  Pools are restored to this level
-		  on reconfiguration.
+		  on reconfiguratoin.
 	- Changed storeClientCopy to give a swap-in failure if 
 	  the number of open disk FD's is above the 'max_open_disk_fds'
 	  limit.  Otherwise, a very loaded cache will end up with
@@ -214,41 +446,14 @@
 	- Fixed logging of hierarchy codes for SSL requests (Henrik
 	  Nordstrom).
 	- Added some descriptions to mib.txt.
-	- Fixed a bug with non-hierarchical requests (e.g. POST)
+	- Fixed a bug with non-hierarchical requests (e.g. POST) 
 	  and cache digests.  We used to look up non-hierarchical
 	  requests in peer digests.  A false hit may cause Squid
 	  to forward a request to a sibling.  In combination with
 	  'Cache-control: only-if-cached, this generates 504 Gateway
 	  Timeout responses and the request may not be re-forwardable.
-	- Fixed a filedescriptor leak for some aborted requests.
-
-	2.2.STABLE5:
+	- Fixed a filedescriptor leak for some aborted requests.  
 
-	- Changed configure to look for IP-Filter header files
-	  in both /usr/include and /usr/include/netinet.
-	- Fixed an ACL subdomain comparison bug (aclDomainCompare).
-	- Fixed an ACL host <=> domain comparison bug
-	  (aclHostDomainCompare).
-	- Fixed a "xstrdup: tried to dup a NULL pointer!" bug
-	  caused by illegal hostname characters when certain
-	  ACL types are in use.
-	- Fixed res_init() bug in dnsserver.  We used to call
-	  res_init(), and then clear the RES_INIT bit in
-	  _res.options.  This caused res_init() to be
-	  called again as soon as we use gethostbyname(), and
-	  this second initialization wipes out our changing
-	  the nameservers.  The fix is just to NOT set
-	  _res.options to RES_DEFAULT after calling res_init().
-	- Changed FTP to close data sockets as soon as the transfer
-	  ends, rather than waiting for the reply message on the
-	  control socket (Alexander V. Lukyanov).
-	- Fixed some buffering problems between Squid and the
-	  unlinkd process.  By using file_write(), unlink requests
-	  were being buffered and experiencing long delays under
-	  heavy load.  Now use use good ol' write() instead.  Also
-	  added some feedback from unlinkd to squid so we can track
-	  the unlink request queue.  If the queue becomes too large,
-	  we block a little and wait for some acks from unlinkd.
 
 Changes to Squid-2.1 (November 16, 1998):
 
Index: squid/acconfig.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/Attic/acconfig.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/acconfig.h	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/acconfig.h	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -20,7 +20,7 @@
  *
  */
 @ TOP @
-/* $Id: acconfig.h,v 1.1.1.2 2000/01/26 03:23:09 hno Exp $ */
+/* $Id: acconfig.h,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $ */
 
 /*********************************
  * START OF CONFIGURABLE OPTIONS *
@@ -48,6 +48,9 @@
 /* Define to use async disk I/O operations */
 #undef USE_ASYNC_IO
 
+/* Defines how many threads to use for async I/O */
+#undef NUMTHREADS
+
 /*
  * If you want to use Squid's ICMP features (highly recommended!) then
  * define this.  When USE_ICMP is defined, Squid will send ICMP pings
@@ -83,6 +86,11 @@
 #undef SQUID_SNMP
 
 /*
+ * Define to enable WCCP
+ */
+#define USE_WCCP 1
+
+/*
  * Squid frequently calls gettimeofday() for accurate timestamping.
  * If you are concerned that gettimeofday() is called too often, and
  * could be causing performance degradation, then you can define
@@ -229,6 +237,27 @@
 #undef HAVE_STATVFS
 
 /*
- * we check for struct mallinfo
+ * If --disable-internal-dns was given to configure, then we'll use
+ * the dnsserver processes instead.
+ */
+#undef USE_DNSSERVERS
+
+/*
+ * we check for the existance of struct mallinfo
  */
 #undef HAVE_STRUCT_MALLINFO
+
+/*
+ * Do we want to use truncate(2) or unlink(2)?
+ */
+#undef USE_TRUNCATE
+
+/*
+ * Allow underscores in host names
+ */
+#undef ALLOW_HOSTNAME_UNDERSCORES
+
+/*
+ * Use the heap-based replacement techniques
+ */
+#undef HEAP_REPLACEMENT
Index: squid/configure
===================================================================
RCS file: /cvsroot/squid-sf//squid/Attic/configure,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/configure	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/configure	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -27,7 +27,11 @@
 ac_help="$ac_help
   --enable-carp           Enable CARP support"
 ac_help="$ac_help
-  --enable-async-io       Do ASYNC disk I/O using threads"
+  --enable-async-io[=N_THREADS]
+                          Do ASYNC disk I/O using threads.
+                          N_THREADS is the number of worker threads
+                          defaults to 16. See also src/squid.h for
+                          some additional platform tuning"
 ac_help="$ac_help
   --enable-icmp           Enable ICMP pinging"
 ac_help="$ac_help
@@ -37,6 +41,8 @@
 ac_help="$ac_help
   --enable-useragent-log  Enable logging of User-Agent header"
 ac_help="$ac_help
+  --disable-wccp      Disable Web Cache Coordination Protocol"
+ac_help="$ac_help
   --enable-kill-parent-hack
                           Kill parent on shutdown"
 ac_help="$ac_help
@@ -83,6 +89,29 @@
   --disable-ident-lookups
                           This allows you to remove code that performs
                           Ident (RFC 931) lookups."
+ac_help="$ac_help
+  --disable-internal-dns  This prevents Squid from directly sending and
+                          receiving DNS messages, and instead enables the
+                          old external 'dnsserver' processes."
+ac_help="$ac_help
+  --enable-truncate       This uses truncate() instead of unlink() when
+                          removing cache files.  Truncate gives a little
+                          performance improvement, but may cause problems
+                          when used with async I/O.  Truncate uses more
+                          filesystem inodes than unlink.."
+ac_help="$ac_help
+  --enable-underscores    Squid by default rejects any host names with _
+                          in their name to conform with internet standars.
+                          If you disagree with this you may allow _ in
+                          hostnames by using this switch, provided that
+                          the resolver library on the host where Squid runs
+                          does not reject _ in hostnames..."
+ac_help="$ac_help
+  --enable-heap-replacement
+                          This option allows you to use various cache
+                          replacement algorithms, instead of the standard
+                          LRU algorithm.
+                          "
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -591,7 +620,7 @@
 
 
 
-# From configure.in Revision: 1.167.2.14 
+# From configure.in Revision: 1.176.2.12 
 ac_aux_dir=
 for ac_dir in cfgaux $srcdir/cfgaux; do
   if test -f $ac_dir/install-sh; then
@@ -619,7 +648,7 @@
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:623: checking host system type" >&5
+echo "configure:652: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -687,7 +716,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:691: checking for $ac_word" >&5
+echo "configure:720: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -716,7 +745,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:720: checking for $ac_word" >&5
+echo "configure:749: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -764,7 +793,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:768: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:797: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -774,11 +803,11 @@
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 778 "configure"
+#line 807 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -798,12 +827,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:802: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:831: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:807: checking whether we are using GNU C" >&5
+echo "configure:836: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -812,7 +841,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:816: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -827,7 +856,7 @@
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:831: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:860: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -913,70 +942,59 @@
     fi
 fi
 
-if test "x$ac_cv_enabled_dlmalloc" = "x"; then
-    case "$host" in
-	i386-*-solaris2.*)
-		echo "Enabling dlmalloc for $host"
-		ac_cv_enabled_dlmalloc="yes"
-		;;
-    esac
-fi
-
 # Check whether --enable-dlmalloc or --disable-dlmalloc was given.
 if test "${enable_dlmalloc+set}" = set; then
   enableval="$enable_dlmalloc"
   
- if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
-   # Ok. dlmalloc was enabled before, but state may be changed.
-   # we have to test these again
-   unset ac_cv_func_mallinfo
-   unset ac_cv_func_mallocblksize
-   unset ac_cv_func_free
-   unset ac_cv_func_realloc
-   unset ac_cv_func_memalign
-   unset ac_cv_func_valloc
-   unset ac_cv_func_pvalloc
-   unset ac_cv_func_calloc
-   unset ac_cv_func_cfree
-   unset ac_cv_func_malloc_trim
-   unset ac_cv_func_malloc_usable_size
-   unset ac_cv_func_malloc_stats
-   unset ac_cv_func_mallopt
-   unset ac_cv_lib_gnumalloc
-   unset ac_cv_header_gnumalloc_h
-   unset ac_cv_lib_malloc
-   unset ac_cv_enabled_dlmalloc
- fi
  case "$enableval" in
  'yes')
+    use_dlmalloc="yes"
     LIBDLMALLOC="libdlmalloc.a"
     LIB_MALLOC="-L../lib -ldlmalloc"
-    ac_cv_func_mallinfo="yes"
-    ac_cv_func_mallocblksize="no"
-    ac_cv_func_free="yes"
-    ac_cv_func_realloc="yes"
-    ac_cv_func_memalign="yes"
-    ac_cv_func_valloc="yes"
-    ac_cv_func_pvalloc="yes"
-    ac_cv_func_calloc="yes"
-    ac_cv_func_cfree="yes"
-    ac_cv_func_malloc_trim="yes"
-    ac_cv_func_malloc_usable_size="yes"
-    ac_cv_func_malloc_stats="yes"
-    ac_cv_func_mallopt="yes"
-    ac_cv_lib_gnumalloc="no"
-    ac_cv_header_gnumalloc_h="no"
-    ac_cv_lib_malloc="no"
-    ac_cv_enabled_dlmalloc="yes"
-    echo "dlmalloc build enabled"
+    echo "dlmalloc enabled"
     ;;
  'no')
-    # Disabled explicitly.
-    echo "dlmalloc disabled."
+    use_dlmalloc="no"
+    echo "dlmalloc disabled"
     ;;
- *)
-    # Use already installed dlmalloc library.
-    LIB_MALLOC="${enableval}"
+ *) use_dlmalloc="yes"
+    LIB_MALLOC="$enableval"
+    echo "dlmalloc enabled with $LIB_MALLOC"
+ esac
+
+fi
+
+if test "${use_dlmalloc-unset}" = unset; then
+    case "$host" in
+	i386-*-solaris2.*)
+		echo "Enabling dlmalloc for $host"
+		use_dlmalloc="yes"
+		;;
+    esac
+fi
+if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
+    # Ok. dlmalloc was enabled before, but state may be changed.
+    # we have to test these again
+    unset ac_cv_func_mallinfo
+    unset ac_cv_func_mallocblksize
+    unset ac_cv_func_free
+    unset ac_cv_func_realloc
+    unset ac_cv_func_memalign
+    unset ac_cv_func_valloc
+    unset ac_cv_func_pvalloc
+    unset ac_cv_func_calloc
+    unset ac_cv_func_cfree
+    unset ac_cv_func_malloc_trim
+    unset ac_cv_func_malloc_usable_size
+    unset ac_cv_func_malloc_stats
+    unset ac_cv_func_mallinfo
+    unset ac_cv_func_mallopt
+    unset ac_cv_lib_gnumalloc
+    unset ac_cv_header_gnumalloc_h
+    unset ac_cv_lib_malloc
+    unset ac_cv_enabled_dlmalloc
+fi
+if test "$use_dlmalloc" = yes; then
     ac_cv_func_mallinfo="yes"
     ac_cv_func_mallocblksize="no"
     ac_cv_func_free="yes"
@@ -994,34 +1012,6 @@
     ac_cv_header_gnumalloc_h="no"
     ac_cv_lib_malloc="no"
     ac_cv_enabled_dlmalloc="yes"
-    echo "Use installed dlmalloc."
-    ;;
- esac
- 
-else
-  
- if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
-   # Ok. dlmalloc was enabled before, but now disabled.
-   # we have to test these again
-   unset ac_cv_func_mallinfo
-   unset ac_cv_func_mallocblksize
-   unset ac_cv_func_free
-   unset ac_cv_func_realloc
-   unset ac_cv_func_memalign
-   unset ac_cv_func_valloc
-   unset ac_cv_func_pvalloc
-   unset ac_cv_func_calloc
-   unset ac_cv_func_cfree
-   unset ac_cv_func_malloc_trim
-   unset ac_cv_func_malloc_usable_size
-   unset ac_cv_func_malloc_stats
-   unset ac_cv_func_mallopt
-   unset ac_cv_lib_gnumalloc
-   unset ac_cv_header_gnumalloc_h
-   unset ac_cv_lib_malloc
-   unset ac_cv_enabled_dlmalloc
- fi
- 
 fi
 
 
@@ -1097,7 +1087,26 @@
 # Check whether --enable-async_io or --disable-async_io was given.
 if test "${enable_async_io+set}" = set; then
   enableval="$enable_async_io"
-   if test "$enableval" = "yes" ; then
+   case "$enableval" in
+  yes)
+    async_io=yes
+    ;;
+  no)
+    async_io=''
+    ;;
+  *)
+    async_io=yes
+    cat >> confdefs.h <<EOF
+#define NUMTHREADS $enableval
+EOF
+
+    ;;
+  esac
+
+fi
+
+
+if test -n "$async_io" ; then
     echo "Async I/O enabled"
     async_io=yes
     cat >> confdefs.h <<\EOF
@@ -1116,13 +1125,10 @@
 	fi
 	;;
     esac
-  fi
-
 fi
 
 
 
-
 # Check whether --enable-icmp or --disable-icmp was given.
 if test "${enable_icmp+set}" = set; then
   enableval="$enable_icmp"
@@ -1181,6 +1187,25 @@
 fi
 
 
+# Check whether --enable-wccp or --disable-wccp was given.
+if test "${enable_wccp+set}" = set; then
+  enableval="$enable_wccp"
+   if test "$enableval" = "no" ; then
+    echo "Web Cache Coordination Protocol disabled"
+    cat >> confdefs.h <<\EOF
+#define USE_WCCP 0
+EOF
+
+  else
+    cat >> confdefs.h <<\EOF
+#define USE_WCCP 1
+EOF
+
+  fi
+
+fi
+      
+
 # Check whether --enable-kill_parent_hack or --disable-kill_parent_hack was given.
 if test "${enable_kill_parent_hack+set}" = set; then
   enableval="$enable_kill_parent_hack"
@@ -1428,6 +1453,67 @@
 fi
 
 
+# Check whether --enable-internal-dns or --disable-internal-dns was given.
+if test "${enable_internal_dns+set}" = set; then
+  enableval="$enable_internal_dns"
+   if test "$enableval" = "no" ; then
+    echo "Disabling Internal DNS queries"
+    cat >> confdefs.h <<\EOF
+#define USE_DNSSERVERS 1
+EOF
+
+  else
+    cat >> confdefs.h <<\EOF
+#define USE_DNSSERVERS 0
+EOF
+
+  fi
+
+fi
+
+
+# Check whether --enable-truncate or --disable-truncate was given.
+if test "${enable_truncate+set}" = set; then
+  enableval="$enable_truncate"
+   if test "$enableval" = "yes" ; then
+    echo "Enabling truncate instead of unlink"
+    cat >> confdefs.h <<\EOF
+#define USE_TRUNCATE 1
+EOF
+
+  fi
+
+fi
+
+
+# Check whether --enable-underscores or --disable-underscores was given.
+if test "${enable_underscores+set}" = set; then
+  enableval="$enable_underscores"
+   if test "$enableval" = "yes" ; then
+    echo "Enabling the use of underscores in host names"
+    cat >> confdefs.h <<\EOF
+#define ALLOW_HOSTNAME_UNDERSCORES 1
+EOF
+
+  fi
+
+fi
+
+
+# Check whether --enable-heap-replacement or --disable-heap-replacement was given.
+if test "${enable_heap_replacement+set}" = set; then
+  enableval="$enable_heap_replacement"
+   if test "$enableval" = "yes" ; then
+    echo "Enabling HEAP_REPLACEMENT"
+    cat >> confdefs.h <<\EOF
+#define HEAP_REPLACEMENT 1
+EOF
+
+  fi
+
+fi
+
+
 # Force some compilers to use ANSI features
 #
 case "$host" in
@@ -1448,7 +1534,7 @@
 esac
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1452: checking how to run the C preprocessor" >&5
+echo "configure:1538: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1463,13 +1549,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1467 "configure"
+#line 1553 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1473: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1559: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1480,13 +1566,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1484 "configure"
+#line 1570 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1490: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1519,7 +1605,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1523: checking for a BSD compatible install" >&5
+echo "configure:1609: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1571,7 +1657,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1575: checking for $ac_word" >&5
+echo "configure:1661: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1598,7 +1684,7 @@
 fi
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1602: checking whether ln -s works" >&5
+echo "configure:1688: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1621,7 +1707,7 @@
 # Extract the first word of "sh", so it can be a program name with args.
 set dummy sh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1625: checking for $ac_word" >&5
+echo "configure:1711: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_SH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1653,7 +1739,7 @@
 # Extract the first word of "false", so it can be a program name with args.
 set dummy false; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1657: checking for $ac_word" >&5
+echo "configure:1743: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_FALSE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1685,7 +1771,7 @@
 # Extract the first word of "true", so it can be a program name with args.
 set dummy true; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1689: checking for $ac_word" >&5
+echo "configure:1775: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_TRUE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1717,7 +1803,7 @@
 # Extract the first word of "rm", so it can be a program name with args.
 set dummy rm; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1721: checking for $ac_word" >&5
+echo "configure:1807: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_RM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1749,7 +1835,7 @@
 # Extract the first word of "mv", so it can be a program name with args.
 set dummy mv; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1753: checking for $ac_word" >&5
+echo "configure:1839: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MV'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1781,7 +1867,7 @@
 # Extract the first word of "mkdir", so it can be a program name with args.
 set dummy mkdir; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1785: checking for $ac_word" >&5
+echo "configure:1871: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MKDIR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1813,7 +1899,7 @@
 # Extract the first word of "ln", so it can be a program name with args.
 set dummy ln; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1817: checking for $ac_word" >&5
+echo "configure:1903: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_LN'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1845,7 +1931,7 @@
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1849: checking for $ac_word" >&5
+echo "configure:1935: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1877,7 +1963,7 @@
 # Extract the first word of "makedepend", so it can be a program name with args.
 set dummy makedepend; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1881: checking for $ac_word" >&5
+echo "configure:1967: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MAKEDEPEND'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1909,7 +1995,7 @@
 # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1913: checking for $ac_word" >&5
+echo "configure:1999: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1959,12 +2045,12 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1963: checking for $ac_hdr that defines DIR" >&5
+echo "configure:2049: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1968 "configure"
+#line 2054 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -1972,7 +2058,7 @@
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1976: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2062: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -1997,7 +2083,7 @@
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:2001: checking for opendir in -ldir" >&5
+echo "configure:2087: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2005,7 +2091,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2009 "configure"
+#line 2095 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2016,7 +2102,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:2020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2038,7 +2124,7 @@
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:2042: checking for opendir in -lx" >&5
+echo "configure:2128: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2046,7 +2132,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2050 "configure"
+#line 2136 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2057,7 +2143,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:2061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2080,12 +2166,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2084: checking for ANSI C header files" >&5
+echo "configure:2170: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2089 "configure"
+#line 2175 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2093,7 +2179,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2097: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2110,7 +2196,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2114 "configure"
+#line 2200 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2128,7 +2214,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2132 "configure"
+#line 2218 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2149,7 +2235,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2153 "configure"
+#line 2239 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2160,7 +2246,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2247,17 +2333,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2251: checking for $ac_hdr" >&5
+echo "configure:2337: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2256 "configure"
+#line 2342 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2261: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2347: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2285,12 +2371,12 @@
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2289: checking for working const" >&5
+echo "configure:2375: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2294 "configure"
+#line 2380 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2339,7 +2425,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2343: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2429: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2360,14 +2446,14 @@
 fi
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:2364: checking whether byte ordering is bigendian" >&5
+echo "configure:2450: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 2371 "configure"
+#line 2457 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2378,11 +2464,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2382: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2468: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 2386 "configure"
+#line 2472 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2393,7 +2479,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2397: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2483: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -2413,7 +2499,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2417 "configure"
+#line 2503 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -2426,7 +2512,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:2430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -2451,20 +2537,20 @@
 
 
 echo $ac_n "checking if ANSI prototypes work""... $ac_c" 1>&6
-echo "configure:2455: checking if ANSI prototypes work" >&5
+echo "configure:2541: checking if ANSI prototypes work" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ansi_prototypes'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2461 "configure"
+#line 2547 "configure"
 #include "confdefs.h"
 int foo(char *); int foo (char *bar) {return 1;}
 int main() {
 foo("bar")
 ; return 0; }
 EOF
-if { (eval echo configure:2468: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ansi_prototypes="yes"
 else
@@ -2486,13 +2572,13 @@
 fi
 
 echo $ac_n "checking for tm->tm_gmtoff""... $ac_c" 1>&6
-echo "configure:2490: checking for tm->tm_gmtoff" >&5
+echo "configure:2576: checking for tm->tm_gmtoff" >&5
 if eval "test \"`echo '$''{'ac_cv_have_tm_gmoff'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2496 "configure"
+#line 2582 "configure"
 #include "confdefs.h"
 #include <time.h>
 #include <sys/time.h>
@@ -2501,7 +2587,7 @@
       foo.tm_gmtoff = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2505: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_tm_gmoff="yes"
 else
@@ -2523,13 +2609,13 @@
 fi
 
 echo $ac_n "checking for struct mallinfo""... $ac_c" 1>&6
-echo "configure:2527: checking for struct mallinfo" >&5
+echo "configure:2613: checking for struct mallinfo" >&5
 if eval "test \"`echo '$''{'ac_cv_have_struct_mallinfo'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2533 "configure"
+#line 2619 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if HAVE_MALLOC_H
@@ -2547,7 +2633,7 @@
     foo.keepcost = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2551: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2637: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_struct_mallinfo="yes"
 else
@@ -2569,13 +2655,13 @@
 fi
 
 echo $ac_n "checking for extended mallinfo""... $ac_c" 1>&6
-echo "configure:2573: checking for extended mallinfo" >&5
+echo "configure:2659: checking for extended mallinfo" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ext_mallinfo'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2579 "configure"
+#line 2665 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <malloc.h>
@@ -2584,7 +2670,7 @@
       foo.mxfast = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2588: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2674: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ext_mallinfo="yes"
 else
@@ -2606,13 +2692,13 @@
 fi
 
 echo $ac_n "checking for struct rusage""... $ac_c" 1>&6
-echo "configure:2610: checking for struct rusage" >&5
+echo "configure:2696: checking for struct rusage" >&5
 if eval "test \"`echo '$''{'ac_cv_have_struct_rusage'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2616 "configure"
+#line 2702 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TIME_H
@@ -2625,7 +2711,7 @@
 struct rusage R;
 ; return 0; }
 EOF
-if { (eval echo configure:2629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_struct_rusage="yes"
 else
@@ -2647,13 +2733,13 @@
 fi
 
 echo $ac_n "checking for ip->ip_hl""... $ac_c" 1>&6
-echo "configure:2651: checking for ip->ip_hl" >&5
+echo "configure:2737: checking for ip->ip_hl" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ip_hl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 2657 "configure"
+#line 2743 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <netinet/in.h>
@@ -2670,7 +2756,7 @@
       ip.ip_hl= 0;
 ; return 0; }
 EOF
-if { (eval echo configure:2674: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2760: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ip_hl="yes"
 else
@@ -2692,7 +2778,7 @@
 fi
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:2696: checking size of int" >&5
+echo "configure:2782: checking size of int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2700,7 +2786,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2704 "configure"
+#line 2790 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2711,7 +2797,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:2715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -2731,7 +2817,7 @@
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:2735: checking size of long" >&5
+echo "configure:2821: checking size of long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2739,7 +2825,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2743 "configure"
+#line 2829 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2750,7 +2836,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:2754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -2770,7 +2856,7 @@
 
 
 echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:2774: checking size of void *" >&5
+echo "configure:2860: checking size of void *" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2778,7 +2864,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2782 "configure"
+#line 2868 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2789,7 +2875,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:2793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_void_p=`cat conftestval`
 else
@@ -2812,19 +2898,19 @@
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:2816: checking for working alloca.h" >&5
+echo "configure:2902: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2821 "configure"
+#line 2907 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:2828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -2845,12 +2931,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:2849: checking for alloca" >&5
+echo "configure:2935: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2854 "configure"
+#line 2940 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2873,7 +2959,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:2877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -2905,12 +2991,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2909: checking whether alloca needs Cray hooks" >&5
+echo "configure:2995: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2914 "configure"
+#line 3000 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2935,12 +3021,12 @@
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2939: checking for $ac_func" >&5
+echo "configure:3025: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 3030 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2963,7 +3049,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2990,7 +3076,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2994: checking stack direction for C alloca" >&5
+echo "configure:3080: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2998,7 +3084,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 3002 "configure"
+#line 3088 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -3017,7 +3103,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:3021: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -3040,12 +3126,12 @@
 
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:3044: checking for pid_t" >&5
+echo "configure:3130: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3049 "configure"
+#line 3135 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3073,12 +3159,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:3077: checking for size_t" >&5
+echo "configure:3163: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3082 "configure"
+#line 3168 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3106,12 +3192,12 @@
 fi
 
 echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:3110: checking for ssize_t" >&5
+echo "configure:3196: checking for ssize_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3115 "configure"
+#line 3201 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3139,12 +3225,12 @@
 fi
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:3143: checking for off_t" >&5
+echo "configure:3229: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3148 "configure"
+#line 3234 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3172,12 +3258,12 @@
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:3176: checking for mode_t" >&5
+echo "configure:3262: checking for mode_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3181 "configure"
+#line 3267 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3205,12 +3291,12 @@
 fi
 
 echo $ac_n "checking for fd_mask""... $ac_c" 1>&6
-echo "configure:3209: checking for fd_mask" >&5
+echo "configure:3295: checking for fd_mask" >&5
 if eval "test \"`echo '$''{'ac_cv_type_fd_mask'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3214 "configure"
+#line 3300 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3239,13 +3325,13 @@
 
 
 echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
-echo "configure:3243: checking for socklen_t" >&5
+echo "configure:3329: checking for socklen_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 3249 "configure"
+#line 3335 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -3276,7 +3362,7 @@
 fi
 
 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:3280: checking for main in -lnsl" >&5
+echo "configure:3366: checking for main in -lnsl" >&5
 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3284,14 +3370,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3288 "configure"
+#line 3374 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3319,7 +3405,7 @@
 fi
 
 echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
-echo "configure:3323: checking for main in -lsocket" >&5
+echo "configure:3409: checking for main in -lsocket" >&5
 ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3327,14 +3413,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3331 "configure"
+#line 3417 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3366,7 +3452,7 @@
   echo "skipping libmalloc check (--enable-dlmalloc specified)"
 else
   echo $ac_n "checking for main in -lgnumalloc""... $ac_c" 1>&6
-echo "configure:3370: checking for main in -lgnumalloc" >&5
+echo "configure:3456: checking for main in -lgnumalloc" >&5
 ac_lib_var=`echo gnumalloc'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3374,14 +3460,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lgnumalloc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3378 "configure"
+#line 3464 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3385: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3424,7 +3510,7 @@
 			*)
   
 				echo $ac_n "checking for main in -lmalloc""... $ac_c" 1>&6
-echo "configure:3428: checking for main in -lmalloc" >&5
+echo "configure:3514: checking for main in -lmalloc" >&5
 ac_lib_var=`echo malloc'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3432,14 +3518,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lmalloc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3436 "configure"
+#line 3522 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3472,7 +3558,7 @@
 fi
 
 echo $ac_n "checking for main in -lbsd""... $ac_c" 1>&6
-echo "configure:3476: checking for main in -lbsd" >&5
+echo "configure:3562: checking for main in -lbsd" >&5
 ac_lib_var=`echo bsd'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3480,14 +3566,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lbsd  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3484 "configure"
+#line 3570 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3515,7 +3601,7 @@
 fi
 
 echo $ac_n "checking for main in -lregex""... $ac_c" 1>&6
-echo "configure:3519: checking for main in -lregex" >&5
+echo "configure:3605: checking for main in -lregex" >&5
 ac_lib_var=`echo regex'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3523,14 +3609,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lregex  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3527 "configure"
+#line 3613 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3551,7 +3637,7 @@
 fi
 
 echo $ac_n "checking for gethostbyname in -lbind""... $ac_c" 1>&6
-echo "configure:3555: checking for gethostbyname in -lbind" >&5
+echo "configure:3641: checking for gethostbyname in -lbind" >&5
 ac_lib_var=`echo bind'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3559,7 +3645,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lbind  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3563 "configure"
+#line 3649 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3570,7 +3656,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:3574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3604,7 +3690,7 @@
 		;;
 	*)
 		echo $ac_n "checking for inet_aton in -lresolv""... $ac_c" 1>&6
-echo "configure:3608: checking for inet_aton in -lresolv" >&5
+echo "configure:3694: checking for inet_aton in -lresolv" >&5
 ac_lib_var=`echo resolv'_'inet_aton | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3612,7 +3698,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3616 "configure"
+#line 3702 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3623,7 +3709,7 @@
 inet_aton()
 ; return 0; }
 EOF
-if { (eval echo configure:3627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3639,7 +3725,7 @@
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for inet_aton in -l44bsd""... $ac_c" 1>&6
-echo "configure:3643: checking for inet_aton in -l44bsd" >&5
+echo "configure:3729: checking for inet_aton in -l44bsd" >&5
 ac_lib_var=`echo 44bsd'_'inet_aton | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3647,7 +3733,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-l44bsd  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3651 "configure"
+#line 3737 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3658,7 +3744,7 @@
 inet_aton()
 ; return 0; }
 EOF
-if { (eval echo configure:3662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3690,7 +3776,7 @@
 fi
 
 		echo $ac_n "checking for main in -lresolv""... $ac_c" 1>&6
-echo "configure:3694: checking for main in -lresolv" >&5
+echo "configure:3780: checking for main in -lresolv" >&5
 ac_lib_var=`echo resolv'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3698,14 +3784,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3702 "configure"
+#line 3788 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3736,7 +3822,7 @@
     esac
 fi
 echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
-echo "configure:3740: checking for main in -lm" >&5
+echo "configure:3826: checking for main in -lm" >&5
 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3744,14 +3830,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3748 "configure"
+#line 3834 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3780,7 +3866,7 @@
 
 
 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:3784: checking for crypt in -lcrypt" >&5
+echo "configure:3870: checking for crypt in -lcrypt" >&5
 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3788,7 +3874,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3792 "configure"
+#line 3878 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3799,7 +3885,7 @@
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:3803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3832,7 +3918,7 @@
 
 
 echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6
-echo "configure:3836: checking for main in -lpthread" >&5
+echo "configure:3922: checking for main in -lpthread" >&5
 ac_lib_var=`echo pthread'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3840,14 +3926,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3844 "configure"
+#line 3930 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3882,7 +3968,7 @@
 case "$host" in
 	*-pc-sco3.2*)
 		echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:3886: checking for strftime in -lintl" >&5
+echo "configure:3972: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3890,7 +3976,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3894 "configure"
+#line 3980 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3901,7 +3987,7 @@
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:3905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4025,7 +4111,6 @@
 for ac_func in \
 	bcopy \
 	crypt \
-	drand48 \
 	fchmod \
 	getdtablesize \
 	getpagesize \
@@ -4049,6 +4134,7 @@
 	res_init \
 	rint \
 	seteuid \
+	setgroups \
 	setpgrp \
 	setrlimit \
 	getrlimit \
@@ -4059,18 +4145,17 @@
 	srandom \
 	sysconf \
 	syslog \
-	tempnam \
 	timegm \
 	vsnprintf \
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4069: checking for $ac_func" >&5
+echo "configure:4154: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4074 "configure"
+#line 4159 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4093,7 +4178,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4126,12 +4211,12 @@
 	
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4130: checking for $ac_func" >&5
+echo "configure:4215: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4135 "configure"
+#line 4220 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4154,7 +4239,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4181,7 +4266,7 @@
 fi
 
 echo $ac_n "checking if setresuid is implemented""... $ac_c" 1>&6
-echo "configure:4185: checking if setresuid is implemented" >&5
+echo "configure:4270: checking if setresuid is implemented" >&5
 if eval "test \"`echo '$''{'ac_cv_func_setresuid'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4189,7 +4274,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4193 "configure"
+#line 4278 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4202,7 +4287,7 @@
   }
   
 EOF
-if { (eval echo configure:4206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_setresuid="yes"
 else
@@ -4227,7 +4312,7 @@
 
 if test "$IPF_TRANSPARENT" ; then
     echo $ac_n "checking if IP-Filter header files are installed""... $ac_c" 1>&6
-echo "configure:4231: checking if IP-Filter header files are installed" >&5
+echo "configure:4316: checking if IP-Filter header files are installed" >&5
     if test "$ac_cv_header_ip_compat_h" = "yes" &&
        test "$ac_cv_header_ip_fil_h" = "yes" &&
        test "$ac_cv_header_ip_nat_h" = "yes" ; then
@@ -4270,13 +4355,13 @@
     esac
 fi
 echo $ac_n "checking if GNUregex needs to be compiled""... $ac_c" 1>&6
-echo "configure:4274: checking if GNUregex needs to be compiled" >&5
+echo "configure:4359: checking if GNUregex needs to be compiled" >&5
 if test -z "$USE_GNUREGEX"; then
 if test "$ac_cv_func_regcomp" = "no" || test "$USE_GNUREGEX" = "yes" ; then
 	USE_GNUREGEX="yes"
 else
 	cat > conftest.$ac_ext <<EOF
-#line 4280 "configure"
+#line 4365 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <regex.h>
@@ -4284,7 +4369,7 @@
 regex_t t; regcomp(&t,"",0);
 ; return 0; }
 EOF
-if { (eval echo configure:4288: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4373: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   USE_GNUREGEX="no"
 else
@@ -4315,12 +4400,12 @@
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4319: checking for $ac_func" >&5
+echo "configure:4404: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4324 "configure"
+#line 4409 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4343,7 +4428,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4347: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4371,12 +4456,12 @@
 
 
 echo $ac_n "checking Default FD_SETSIZE value""... $ac_c" 1>&6
-echo "configure:4375: checking Default FD_SETSIZE value" >&5
+echo "configure:4460: checking Default FD_SETSIZE value" >&5
 if test "$cross_compiling" = yes; then
   DEFAULT_FD_SETSIZE=256
 else
   cat > conftest.$ac_ext <<EOF
-#line 4380 "configure"
+#line 4465 "configure"
 #include "confdefs.h"
 
 #if HAVE_STDIO_H
@@ -4401,7 +4486,7 @@
 }
 
 EOF
-if { (eval echo configure:4405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   DEFAULT_FD_SETSIZE=`cat conftestval`
 else
@@ -4420,12 +4505,19 @@
 
 
 echo $ac_n "checking Maximum number of filedescriptors we can open""... $ac_c" 1>&6
-echo "configure:4424: checking Maximum number of filedescriptors we can open" >&5
+echo "configure:4509: checking Maximum number of filedescriptors we can open" >&5
+TLDFLAGS="$LDFLAGS"
+case $host in
+i386-unknown-freebsd*)
+    if echo "$LDFLAGS" | grep -q pthread; then
+	LDFLAGS=`echo $LDFLAGS | sed -e "s/-pthread//"`
+    fi
+esac
 if test "$cross_compiling" = yes; then
   SQUID_MAXFD=256
 else
   cat > conftest.$ac_ext <<EOF
-#line 4429 "configure"
+#line 4521 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4441,8 +4533,7 @@
      * Number of fds is virtually unlimited in cygwin (sys/param.h)
      */
     i = NOFILE;
-#else
-#if HAVE_SETRLIMIT
+#elif HAVE_SETRLIMIT
     struct rlimit rl;
 #if defined(RLIMIT_NOFILE)
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
@@ -4464,34 +4555,26 @@
     }
 #endif /* RLIMIT_NOFILE */
 #endif /* HAVE_SETRLIMIT */
-#if defined(__linux__) && HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
-	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-		perror("getrlimit: RLIMIT_NOFILE");
-	}
-	i = rl.rlim_cur;
-#elif HAVE_SYSCONF && defined(_SC_OPEN_MAX)
-        i = sysconf(_SC_OPEN_MAX);
-#elif HAVE_GETDTABLESIZE && !defined(__linux__)
-        i = getdtablesize();
-#elif defined(OPEN_MAX)
-        i = OPEN_MAX;
-#elif defined(NOFILE)
-        i = NOFILE;
-#elif defined(_NFILE)
-        i = _NFILE;
-#else
-	while((j=open("/dev/null", 0)) > 0) i=j;
-        close(i); close(i-1);
-	i++;
-#endif
-#endif /* __CYGWIN32__ */
+	/* by starting at 2^14, we will never get higher
+	than 2^15 for SQUID_MAXFD */
+        i = j = 1<<14;
+        while (j) {
+                j >>= 1;
+                if (dup2(0, i) < 0) { 
+                        i -= j;
+                } else {
+                        close(i);
+                        i += j;
+                }
+        }
+        i++;
 	fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", i);
 	exit(0);
 }
 
 EOF
-if { (eval echo configure:4495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   SQUID_MAXFD=`cat conftestval`
 else
@@ -4515,14 +4598,15 @@
     echo "         on how to increase your filedescriptor limit"
     sleep 10
 fi
+LDFLAGS="$TLDFLAGS"
 
 echo $ac_n "checking Default UDP send buffer size""... $ac_c" 1>&6
-echo "configure:4521: checking Default UDP send buffer size" >&5
+echo "configure:4605: checking Default UDP send buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_UDP_SO_SNDBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 4526 "configure"
+#line 4610 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4543,7 +4627,7 @@
 }
 
 EOF
-if { (eval echo configure:4547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   SQUID_UDP_SO_SNDBUF=`cat conftestval`
 else
@@ -4562,12 +4646,12 @@
 
 
 echo $ac_n "checking Default UDP receive buffer size""... $ac_c" 1>&6
-echo "configure:4566: checking Default UDP receive buffer size" >&5
+echo "configure:4650: checking Default UDP receive buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_UDP_SO_RCVBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 4571 "configure"
+#line 4655 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4588,7 +4672,7 @@
 }
 
 EOF
-if { (eval echo configure:4592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   SQUID_UDP_SO_RCVBUF=`cat conftestval`
 else
@@ -4607,12 +4691,12 @@
 
 
 echo $ac_n "checking Default TCP send buffer size""... $ac_c" 1>&6
-echo "configure:4611: checking Default TCP send buffer size" >&5
+echo "configure:4695: checking Default TCP send buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_TCP_SO_SNDBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 4616 "configure"
+#line 4700 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4633,7 +4717,7 @@
 }
 
 EOF
-if { (eval echo configure:4637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   SQUID_TCP_SO_SNDBUF=`cat conftestval`
 else
@@ -4652,12 +4736,12 @@
 
 
 echo $ac_n "checking Default TCP receive buffer size""... $ac_c" 1>&6
-echo "configure:4656: checking Default TCP receive buffer size" >&5
+echo "configure:4740: checking Default TCP receive buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_TCP_SO_RCVBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 4661 "configure"
+#line 4745 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4678,7 +4762,7 @@
 }
 
 EOF
-if { (eval echo configure:4682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   SQUID_TCP_SO_RCVBUF=`cat conftestval`
 else
@@ -4697,19 +4781,19 @@
 
 
 echo $ac_n "checking if sys_errlist is already defined""... $ac_c" 1>&6
-echo "configure:4701: checking if sys_errlist is already defined" >&5
+echo "configure:4785: checking if sys_errlist is already defined" >&5
 if eval "test \"`echo '$''{'ac_cv_needs_sys_errlist'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4706 "configure"
+#line 4790 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main() {
-char *s = sys_errlist0;
+char *s = sys_errlist;
 ; return 0; }
 EOF
-if { (eval echo configure:4713: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_needs_sys_errlist="no"
 else
@@ -4731,16 +4815,16 @@
 fi
 
 echo $ac_n "checking for libresolv _dns_ttl_ hack""... $ac_c" 1>&6
-echo "configure:4735: checking for libresolv _dns_ttl_ hack" >&5
+echo "configure:4819: checking for libresolv _dns_ttl_ hack" >&5
 cat > conftest.$ac_ext <<EOF
-#line 4737 "configure"
+#line 4821 "configure"
 #include "confdefs.h"
 extern int _dns_ttl_;
 int main() {
 return _dns_ttl_;
 ; return 0; }
 EOF
-if { (eval echo configure:4744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 cat >> confdefs.h <<\EOF
@@ -4756,12 +4840,12 @@
 rm -f conftest*
 
 echo $ac_n "checking if inet_ntoa() actually works""... $ac_c" 1>&6
-echo "configure:4760: checking if inet_ntoa() actually works" >&5
+echo "configure:4844: checking if inet_ntoa() actually works" >&5
 if test "$cross_compiling" = yes; then
   INET_NTOA_RESULT="broken"
 else
   cat > conftest.$ac_ext <<EOF
-#line 4765 "configure"
+#line 4849 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4780,7 +4864,7 @@
 }
 
 EOF
-if { (eval echo configure:4784: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   INET_NTOA_RESULT=`cat conftestval`
 else
@@ -4806,9 +4890,9 @@
 
 if test "$ac_cv_header_sys_statvfs_h" = "yes" ; then
 echo $ac_n "checking for working statvfs() interface""... $ac_c" 1>&6
-echo "configure:4810: checking for working statvfs() interface" >&5
+echo "configure:4894: checking for working statvfs() interface" >&5
 cat > conftest.$ac_ext <<EOF
-#line 4812 "configure"
+#line 4896 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -4825,7 +4909,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4829: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_func_statvfs=yes
 else
@@ -4845,12 +4929,12 @@
 fi
 
 echo $ac_n "checking for _res.nsaddr_list""... $ac_c" 1>&6
-echo "configure:4849: checking for _res.nsaddr_list" >&5
+echo "configure:4933: checking for _res.nsaddr_list" >&5
 if eval "test \"`echo '$''{'ac_cv_have_res_nsaddr_list'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4854 "configure"
+#line 4938 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TYPES_H
@@ -4873,7 +4957,7 @@
 _res.nsaddr_list[0];
 ; return 0; }
 EOF
-if { (eval echo configure:4877: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_res_nsaddr_list="yes"
 else
@@ -4895,12 +4979,12 @@
 
 if test $ac_cv_have_res_nsaddr_list = "no" ; then
 echo $ac_n "checking for _res.ns_list""... $ac_c" 1>&6
-echo "configure:4899: checking for _res.ns_list" >&5
+echo "configure:4983: checking for _res.ns_list" >&5
 if eval "test \"`echo '$''{'ac_cv_have_res_ns_list'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4904 "configure"
+#line 4988 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TYPES_H
@@ -4923,7 +5007,7 @@
 _res.ns_list[0].addr;
 ; return 0; }
 EOF
-if { (eval echo configure:4927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_res_ns_list="yes"
 else
@@ -5082,7 +5166,10 @@
 	./errors/Makefile \
 	./auth_modules/dummy \
 	./auth_modules/NCSA/Makefile \
+	./auth_modules/PAM/Makefile \
+	./auth_modules/SMB/Makefile
 	./auth_modules/getpwnam/Makefile \
+	./auth_modules/LDAP/Makefile \
  include/autoconf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
@@ -5213,7 +5300,10 @@
 	./errors/Makefile \
 	./auth_modules/dummy \
 	./auth_modules/NCSA/Makefile \
+	./auth_modules/PAM/Makefile \
+	./auth_modules/SMB/Makefile
 	./auth_modules/getpwnam/Makefile \
+	./auth_modules/LDAP/Makefile \
 "}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
Index: squid/configure.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/configure.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/configure.in	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/configure.in	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -3,13 +3,13 @@
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.1.1.2 2000/01/26 03:23:09 hno Exp $
+dnl  $Id: configure.in,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
 dnl
 dnl
 dnl
 AC_INIT(src/main.c)
 AC_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.1.1.2 $)dnl
+AC_REVISION($Revision: 1.1.1.3 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AC_CONFIG_AUX_DIR(cfgaux)
 
@@ -124,70 +124,57 @@
     fi
 fi
 
-if test "x$ac_cv_enabled_dlmalloc" = "x"; then
-    case "$host" in
-	i386-*-solaris2.*)
-		echo "Enabling dlmalloc for $host"
-		ac_cv_enabled_dlmalloc="yes"
-		;;
-    esac
-fi
-
 dnl Enable optional modules
 AC_ARG_ENABLE(dlmalloc,
 [  --enable-dlmalloc[=LIB] Compile & use the malloc package by Doug Lea],
 [
- if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
-   # Ok. dlmalloc was enabled before, but state may be changed.
-   # we have to test these again
-   unset ac_cv_func_mallinfo
-   unset ac_cv_func_mallocblksize
-   unset ac_cv_func_free
-   unset ac_cv_func_realloc
-   unset ac_cv_func_memalign
-   unset ac_cv_func_valloc
-   unset ac_cv_func_pvalloc
-   unset ac_cv_func_calloc
-   unset ac_cv_func_cfree
-   unset ac_cv_func_malloc_trim
-   unset ac_cv_func_malloc_usable_size
-   unset ac_cv_func_malloc_stats
-   unset ac_cv_func_mallopt
-   unset ac_cv_lib_gnumalloc
-   unset ac_cv_header_gnumalloc_h
-   unset ac_cv_lib_malloc
-   unset ac_cv_enabled_dlmalloc
- fi
  case "$enableval" in
  'yes')
+    use_dlmalloc="yes"
     LIBDLMALLOC="libdlmalloc.a"
     LIB_MALLOC="-L../lib -ldlmalloc"
-    ac_cv_func_mallinfo="yes"
-    ac_cv_func_mallocblksize="no"
-    ac_cv_func_free="yes"
-    ac_cv_func_realloc="yes"
-    ac_cv_func_memalign="yes"
-    ac_cv_func_valloc="yes"
-    ac_cv_func_pvalloc="yes"
-    ac_cv_func_calloc="yes"
-    ac_cv_func_cfree="yes"
-    ac_cv_func_malloc_trim="yes"
-    ac_cv_func_malloc_usable_size="yes"
-    ac_cv_func_malloc_stats="yes"
-    ac_cv_func_mallopt="yes"
-    ac_cv_lib_gnumalloc="no"
-    ac_cv_header_gnumalloc_h="no"
-    ac_cv_lib_malloc="no"
-    ac_cv_enabled_dlmalloc="yes"
-    echo "dlmalloc build enabled"
+    echo "dlmalloc enabled"
     ;;
  'no')
-    # Disabled explicitly.
-    echo "dlmalloc disabled."
+    use_dlmalloc="no"
+    echo "dlmalloc disabled"
     ;;
- *)
-    # Use already installed dlmalloc library.
-    LIB_MALLOC="${enableval}"
+ *) use_dlmalloc="yes"
+    LIB_MALLOC="$enableval"
+    echo "dlmalloc enabled with $LIB_MALLOC"
+ esac
+])
+if test "${use_dlmalloc-unset}" = unset; then
+    case "$host" in
+	i386-*-solaris2.*)
+		echo "Enabling dlmalloc for $host"
+		use_dlmalloc="yes"
+		;;
+    esac
+fi
+if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
+    # Ok. dlmalloc was enabled before, but state may be changed.
+    # we have to test these again
+    unset ac_cv_func_mallinfo
+    unset ac_cv_func_mallocblksize
+    unset ac_cv_func_free
+    unset ac_cv_func_realloc
+    unset ac_cv_func_memalign
+    unset ac_cv_func_valloc
+    unset ac_cv_func_pvalloc
+    unset ac_cv_func_calloc
+    unset ac_cv_func_cfree
+    unset ac_cv_func_malloc_trim
+    unset ac_cv_func_malloc_usable_size
+    unset ac_cv_func_malloc_stats
+    unset ac_cv_func_mallinfo
+    unset ac_cv_func_mallopt
+    unset ac_cv_lib_gnumalloc
+    unset ac_cv_header_gnumalloc_h
+    unset ac_cv_lib_malloc
+    unset ac_cv_enabled_dlmalloc
+fi
+if test "$use_dlmalloc" = yes; then
     ac_cv_func_mallinfo="yes"
     ac_cv_func_mallocblksize="no"
     ac_cv_func_free="yes"
@@ -205,32 +192,8 @@
     ac_cv_header_gnumalloc_h="no"
     ac_cv_lib_malloc="no"
     ac_cv_enabled_dlmalloc="yes"
-    echo "Use installed dlmalloc."
-    ;;
- esac
- ],[
- if test "x$ac_cv_enabled_dlmalloc" = "xyes"; then
-   # Ok. dlmalloc was enabled before, but now disabled.
-   # we have to test these again
-   unset ac_cv_func_mallinfo
-   unset ac_cv_func_mallocblksize
-   unset ac_cv_func_free
-   unset ac_cv_func_realloc
-   unset ac_cv_func_memalign
-   unset ac_cv_func_valloc
-   unset ac_cv_func_pvalloc
-   unset ac_cv_func_calloc
-   unset ac_cv_func_cfree
-   unset ac_cv_func_malloc_trim
-   unset ac_cv_func_malloc_usable_size
-   unset ac_cv_func_malloc_stats
-   unset ac_cv_func_mallopt
-   unset ac_cv_lib_gnumalloc
-   unset ac_cv_header_gnumalloc_h
-   unset ac_cv_lib_malloc
-   unset ac_cv_enabled_dlmalloc
- fi
- ])
+fi
+
 AC_SUBST(LIBDLMALLOC)
 AC_SUBST(LIB_MALLOC)
 
@@ -274,8 +237,26 @@
 ])
 
 AC_ARG_ENABLE(async_io,
-[  --enable-async-io       Do ASYNC disk I/O using threads],
-[ if test "$enableval" = "yes" ; then
+[  --enable-async-io[=N_THREADS]
+                          Do ASYNC disk I/O using threads.
+                          N_THREADS is the number of worker threads
+                          defaults to 16. See also src/squid.h for
+                          some additional platform tuning],
+[ case "$enableval" in
+  yes)
+    async_io=yes
+    ;;
+  no)
+    async_io=''
+    ;;
+  *)
+    async_io=yes
+    AC_DEFINE_UNQUOTED(NUMTHREADS, $enableval)
+    ;;
+  esac
+])
+
+if test -n "$async_io" ; then
     echo "Async I/O enabled"
     async_io=yes
     AC_DEFINE(USE_ASYNC_IO)
@@ -291,8 +272,7 @@
 	fi
 	;;
     esac
-  fi
-])
+fi
 AC_SUBST(ASYNC_OBJS)
 AC_SUBST(SQUID_PTHREAD_LIB)
 
@@ -330,6 +310,16 @@
   fi
 ])
 
+AC_ARG_ENABLE(wccp,  
+[  --disable-wccp      Disable Web Cache Coordination Protocol],
+[ if test "$enableval" = "no" ; then
+    echo "Web Cache Coordination Protocol disabled"
+    AC_DEFINE(USE_WCCP, 0)
+  else
+    AC_DEFINE(USE_WCCP, 1)
+  fi
+])      
+
 AC_ARG_ENABLE(kill_parent_hack,
 [  --enable-kill-parent-hack
                           Kill parent on shutdown],
@@ -513,6 +503,57 @@
   fi
 ])
 
+AC_ARG_ENABLE(internal-dns,
+[  --disable-internal-dns  This prevents Squid from directly sending and
+                          receiving DNS messages, and instead enables the
+                          old external 'dnsserver' processes.],
+[ if test "$enableval" = "no" ; then
+    echo "Disabling Internal DNS queries"
+    AC_DEFINE(USE_DNSSERVERS, 1)
+  else
+    AC_DEFINE(USE_DNSSERVERS, 0)
+  fi
+])
+
+AC_ARG_ENABLE(truncate,
+[  --enable-truncate       This uses truncate() instead of unlink() when
+                          removing cache files.  Truncate gives a little
+                          performance improvement, but may cause problems
+                          when used with async I/O.  Truncate uses more
+                          filesystem inodes than unlink..],
+[ if test "$enableval" = "yes" ; then
+    echo "Enabling truncate instead of unlink"
+    AC_DEFINE(USE_TRUNCATE)
+  fi
+])
+
+dnl Enable underscore in hostnames
+AC_ARG_ENABLE(underscores,
+[  --enable-underscores    Squid by default rejects any host names with _
+                          in their name to conform with internet standars.
+                          If you disagree with this you may allow _ in
+                          hostnames by using this switch, provided that
+                          the resolver library on the host where Squid runs
+                          does not reject _ in hostnames...],
+[ if test "$enableval" = "yes" ; then
+    echo "Enabling the use of underscores in host names"
+    AC_DEFINE(ALLOW_HOSTNAME_UNDERSCORES, 1)
+  fi
+])
+
+dnl Enable HEAP_REPLACEMENT
+AC_ARG_ENABLE(heap-replacement,
+[  --enable-heap-replacement
+                          This option allows you to use various cache
+                          replacement algorithms, instead of the standard
+                          LRU algorithm.
+                          ],
+[ if test "$enableval" = "yes" ; then
+    echo "Enabling HEAP_REPLACEMENT"
+    AC_DEFINE(HEAP_REPLACEMENT, 1)
+  fi
+])
+
 # Force some compilers to use ANSI features
 #
 case "$host" in
@@ -919,7 +960,6 @@
 AC_CHECK_FUNCS(\
 	bcopy \
 	crypt \
-	drand48 \
 	fchmod \
 	getdtablesize \
 	getpagesize \
@@ -943,6 +983,7 @@
 	res_init \
 	rint \
 	seteuid \
+	setgroups \
 	setpgrp \
 	setrlimit \
 	getrlimit \
@@ -953,7 +994,6 @@
 	srandom \
 	sysconf \
 	syslog \
-	tempnam \
 	timegm \
 	vsnprintf \
 )
@@ -1080,6 +1120,14 @@
 
 dnl Not cached since people are likely to tune this
 AC_MSG_CHECKING(Maximum number of filedescriptors we can open)
+dnl shit! FreeBSD's pthreads breaks dup2().
+TLDFLAGS="$LDFLAGS"
+case $host in
+i386-unknown-freebsd*)
+    if echo "$LDFLAGS" | grep -q pthread; then
+	LDFLAGS=`echo $LDFLAGS | sed -e "s/-pthread//"`
+    fi
+esac
 AC_TRY_RUN([
 #include <stdio.h>
 #include <unistd.h>
@@ -1094,8 +1142,7 @@
      * Number of fds is virtually unlimited in cygwin (sys/param.h)
      */
     i = NOFILE;
-#else
-#if HAVE_SETRLIMIT
+#elif HAVE_SETRLIMIT
     struct rlimit rl;
 #if defined(RLIMIT_NOFILE)
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
@@ -1117,27 +1164,19 @@
     }
 #endif /* RLIMIT_NOFILE */
 #endif /* HAVE_SETRLIMIT */
-#if defined(__linux__) && HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
-	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-		perror("getrlimit: RLIMIT_NOFILE");
-	}
-	i = rl.rlim_cur;
-#elif HAVE_SYSCONF && defined(_SC_OPEN_MAX)
-        i = sysconf(_SC_OPEN_MAX);
-#elif HAVE_GETDTABLESIZE && !defined(__linux__)
-        i = getdtablesize();
-#elif defined(OPEN_MAX)
-        i = OPEN_MAX;
-#elif defined(NOFILE)
-        i = NOFILE;
-#elif defined(_NFILE)
-        i = _NFILE;
-#else
-	while((j=open("/dev/null", 0)) > 0) i=j;
-        close(i); close(i-1);
-	i++;
-#endif
-#endif /* __CYGWIN32__ */
+	/* by starting at 2^14, we will never get higher
+	than 2^15 for SQUID_MAXFD */
+        i = j = 1<<14;
+        while (j) {
+                j >>= 1;
+                if (dup2(0, i) < 0) { 
+                        i -= j;
+                } else {
+                        close(i);
+                        i += j;
+                }
+        }
+        i++;
 	fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", i);
 	exit(0);
@@ -1155,6 +1194,7 @@
     echo "         on how to increase your filedescriptor limit"
     sleep 10
 fi
+LDFLAGS="$TLDFLAGS"
 
 dnl Not cached since people are likely to tune this
 AC_MSG_CHECKING(Default UDP send buffer size)
@@ -1261,7 +1301,7 @@
 AC_DEFINE_UNQUOTED(SQUID_TCP_SO_RCVBUF, $SQUID_TCP_SO_RCVBUF)
 
 AC_CACHE_CHECK(if sys_errlist is already defined, ac_cv_needs_sys_errlist,
-  AC_TRY_COMPILE([#include <stdio.h>],[char *s = sys_errlist[0];],
+  AC_TRY_COMPILE([#include <stdio.h>],[char *s = sys_errlist;],
     ac_cv_needs_sys_errlist="no",
     ac_cv_needs_sys_errlist="yes")
 )
@@ -1424,5 +1464,8 @@
 	./errors/Makefile \
 	./auth_modules/dummy \
 	./auth_modules/NCSA/Makefile \
+	./auth_modules/PAM/Makefile \
+	./auth_modules/SMB/Makefile
 	./auth_modules/getpwnam/Makefile \
+	./auth_modules/LDAP/Makefile \
 )
Index: squid/makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/Attic/makefile.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/makefile.in	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,4 +1,4 @@
-# $Id: makefile.in,v 1.1.1.2 2000/01/26 03:23:09 hno Exp $
+# $Id: makefile.in,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
 #
 
 srcdir		= @srcdir@
@@ -15,6 +15,11 @@
 exec_prefix	= @exec_prefix@
 
 SUBDIRS		= lib @makesnmplib@ scripts src icons errors 
+AUTHDIRS	= auth_modules/NCSA \
+		  auth_modules/getpwnam \
+		  auth_modules/PAM \
+		  auth_modules/SMB \
+		  auth_modules/LDAP
 
 noargs: all
 
@@ -37,8 +42,8 @@
 almostclean: clean
 	rm -f config.log makefile
 	rm -f include/paths.h include/autoconf.h include/config.h
-	rm -f auth_modules/NCSA/Makefile auth_modules/dummy
-	@for dir in $(SUBDIRS) contrib; do \
+	rm -f auth_modules/dummy
+	@for dir in $(SUBDIRS) $(AUTHDIRS) contrib; do \
 		echo Making distclean in $$dir; \
 		(cd $$dir; $(MAKE) $(MFLAGS) prefix="$(prefix)" distclean); \
 	done
Index: squid/auth_modules/PAM/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/PAM/Attic/Makefile.in,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/auth_modules/PAM/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/auth_modules/PAM/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.1 2000/01/26 03:25:00 hno Exp $
+#  $Id: Makefile.in,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
Index: squid/auth_modules/PAM/pam_auth.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/PAM/Attic/pam_auth.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/auth_modules/PAM/pam_auth.c	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/auth_modules/PAM/pam_auth.c	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,5 +1,5 @@
 /*
- * $Id: pam_auth.c,v 1.1 2000/01/26 03:25:00 hno Exp $
+ * $Id: pam_auth.c,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
  *
  * PAM authenticator module for Squid.
  * Copyright (C) 1999 Henrik Nordstrom <hno@hem.passagen.se>
Index: squid/auth_modules/SMB/Changelog
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/SMB/Attic/Changelog,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/auth_modules/SMB/Changelog	26 Jan 2000 03:23:09 -0000	1.1.1.1
+++ squid/auth_modules/SMB/Changelog	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,3 +1,33 @@
+28 September 1999, version 0.05
+
+- Easier debugging: added the -d option to smb_auth.
+
+- Bugfix: a password containing a backslash character was always
+  denied. Reported by Menno Stevens.
+
+- The -S option now accepts both slashes and backslashes and
+  allows the share name to be preceded by a (back)slash.
+
+5 June 1999, version 0.04
+
+- Allow for both \n and \r\n end-of-line termination in the
+  proxyauth file located on the PDC. This eliminates the most
+  common installation problem.
+
+- The location of the proxyauth file can be changed (for each
+  domain) using the new -S option. Useful when the NETLOGON
+  share is located on a FAT filesystem.
+  Thanks to Colin Manning <colinm@officeinfo.com.au>.
+
+2 Februari 1999, version 0.03
+
+- Support for pass-through authentication (trust relationships)
+  added. Suggested by Matthew Wood <woodm@newsltd.com.au>.
+
+- Bugfix: smb_auth.sh searched for the PDC only.
+
+- Many documentation improvements.
+
 9 December 1998, version 0.02
 
 - smb_auth now uses Samba instead of pam_smb. This simplifies the
Index: squid/auth_modules/SMB/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/SMB/Attic/Makefile.in,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/auth_modules/SMB/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/auth_modules/SMB/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.1 2000/01/26 03:25:00 hno Exp $
+#  $Id: Makefile.in,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
Index: squid/auth_modules/SMB/smb_auth.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/SMB/Attic/smb_auth.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/auth_modules/SMB/smb_auth.c	26 Jan 2000 03:23:09 -0000	1.1.1.1
+++ squid/auth_modules/SMB/smb_auth.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -27,16 +27,52 @@
 
 struct SMBDOMAIN
 {
-	char				*name;		/* domain name */
-	char				*sname;		/* match this with user input */
-	char				*nmbaddr;	/* name service address */
-	int					nmbcast;	/* broadcast or unicast */
-	struct SMBDOMAIN	*next;		/* linked list */
+	char				*name;			/* domain name */
+	char				*sname;			/* match this with user input */
+	char				*passthrough;	/* pass-through authentication */
+	char				*nmbaddr;		/* name service address */
+	int					nmbcast;		/* broadcast or unicast */
+	char				*authshare;		/* share name of auth file */
+	char				*authfile;		/* pathname of auth file */
+	struct SMBDOMAIN	*next;			/* linked list */
 };
 
 struct SMBDOMAIN *firstdom = NULL;
 struct SMBDOMAIN *lastdom = NULL;
 
+/*
+ * escape the backslash character, since it has a special meaning
+ * to the read command of the bourne shell.
+ */
+
+void print_esc(FILE *p, char *s)
+{
+	char	buf[256];
+	char	*t;
+	int		i = 0;
+
+	for (t = s; *t != '\0'; t++)
+	{
+		if (i > 250)
+		{
+			buf[i] = '\0';
+			(void) fputs(buf, p);
+			i = 0;
+		}
+
+		if (*t == '\\')
+			buf[i++] = '\\';
+
+		buf[i++] = *t;
+	}
+
+	if (i > 0)
+	{
+		buf[i] = '\0';
+		(void) fputs(buf, p);
+	}
+}
+
 void main(int argc, char *argv[])
 {
 	int					i;
@@ -47,6 +83,8 @@
 	char				*pass;
 	char				*domname;
 	FILE				*p;
+	int					debug = 0;
+	char				*shcmd;
 
 	/* make standard output line buffered */
 	if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
@@ -55,6 +93,12 @@
 	/* parse command line arguments */
 	for (i = 1; i < argc; i++)
 	{
+		if (strcmp(argv[i], "-d") == 0)
+		{
+			debug = 1;
+			continue;
+		}
+
 		/* the next options require an argument */
 		if (i + 1 == argc)
 			break;
@@ -65,8 +109,11 @@
 				return;
 
 			dom->name = dom->sname = argv[++i];
+			dom->passthrough = "";
 			dom->nmbaddr = "";
 			dom->nmbcast = NMB_BROADCAST;
+			dom->authshare = "NETLOGON";
+			dom->authfile = "proxyauth";
 			dom->next = NULL;
 
 			/* append to linked list */
@@ -86,6 +133,13 @@
 			continue;
 		}
 
+		if (strcmp(argv[i], "-P") == 0)
+		{
+			if (lastdom != NULL)
+				lastdom->passthrough = argv[++i];
+			continue;
+		}
+
 		if (strcmp(argv[i], "-B") == 0)
 		{
 			if (lastdom != NULL)
@@ -105,8 +159,39 @@
 			}
 			continue;
 		}
+
+		if (strcmp(argv[i], "-S") == 0)
+		{
+			if (lastdom != NULL)
+			{
+				if ((lastdom->authshare = strdup(argv[++i])) == NULL)
+					return;
+
+				/* convert backslashes to forward slashes */
+				for (s = lastdom->authshare; *s != '\0'; s++)
+					if (*s == '\\')
+						*s = '/';
+
+				/* strip leading forward slash from share name */
+				if (*lastdom->authshare == '/')
+					lastdom->authshare++;
+
+				if ((s = strchr(lastdom->authshare, '/')) != NULL)
+  				{
+  					*s = '\0';
+  					lastdom->authfile = s + 1;
+  				}
+			}
+			continue;
+		}
 	}
 
+	shcmd = debug ? HELPERSCRIPT : HELPERSCRIPT " > /dev/null 2>&1";
+
+	/* pass to helper script */
+    if (putenv("SAMBAPREFIX=" SAMBAPREFIX) != 0)
+    	return;
+
 	while (1)
 	{
 		if (fgets(buf, BUFSIZE, stdin) == NULL)
@@ -149,18 +234,22 @@
 			continue;
 		}
 
-		if ((p = popen(HELPERSCRIPT " > /dev/null 2>&1", "w")) == NULL)
+		if ((p = popen(shcmd, "w")) == NULL)
 		{
 			(void) printf("ERR\n");
 			continue;
 		}
 
-		(void) fprintf(p, "%s\n", SAMBAPREFIX);
 		(void) fprintf(p, "%s\n", dom->name);
+		(void) fprintf(p, "%s\n", dom->passthrough);
 		(void) fprintf(p, "%s\n", dom->nmbaddr);
 		(void) fprintf(p, "%d\n", dom->nmbcast);
+		(void) fprintf(p, "%s\n", dom->authshare);
+		(void) fprintf(p, "%s\n", dom->authfile);
 		(void) fprintf(p, "%s\n", user);
-		(void) fprintf(p, "%s\n", pass);
+		/* the password can contain special characters */
+		print_esc(p, pass);
+		(void) fputc('\n', p);
 		(void) fflush(p);
 
 		if (pclose(p) == 0)
Index: squid/auth_modules/SMB/smb_auth.sh
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/SMB/Attic/smb_auth.sh,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/auth_modules/SMB/smb_auth.sh	26 Jan 2000 03:23:09 -0000	1.1.1.1
+++ squid/auth_modules/SMB/smb_auth.sh	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,15 +17,24 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-read SAMBAPREFIX
 read DOMAINNAME
+read PASSTHROUGH
 read NMBADDR
 read NMBCAST
+read AUTHSHARE
+read AUTHFILE
 read SMBUSER
 read SMBPASS
 
 # Find domain controller
 echo "Domain name: $DOMAINNAME"
+if [ -n "$PASSTHROUGH" ]
+then
+  echo "Pass-through authentication: yes: $PASSTHROUGH"
+else
+  echo "Pass-through authentication: no"
+  PASSTHROUGH="$DOMAINNAME"
+fi
 if [ -n "$NMBADDR" ]
 then
   if [ "$NMBCAST" = "1" ]
@@ -38,7 +47,7 @@
   addropt=""
 fi
 echo "Query address options: $addropt"
-dcip=`$SAMBAPREFIX/bin/nmblookup $addropt "$DOMAINNAME#1b" | awk '/^[0-9.]+ / { print $1 ; exit }'`
+dcip=`$SAMBAPREFIX/bin/nmblookup $addropt "$PASSTHROUGH#1c" | awk '/^[0-9.]+ / { print $1 ; exit }'`
 echo "Domain controller IP address: $dcip"
 [ -n "$dcip" ] || exit 1
 
@@ -52,8 +61,11 @@
 USER="$SMBUSER%$SMBPASS"
 export USER
 
-# Read the contents of the file "proxyauth" on the NETLOGON share
-proxyauth=`$SAMBAPREFIX/bin/smbclient //$dcname/NETLOGON -I $dcip -E -W "$DOMAINNAME" -c "get proxyauth -" 2>/dev/null`
-echo "Contents of //$dcname/NETLOGON/proxyauth: $proxyauth"
-[ "$proxyauth" = "allow" ] || exit 1
+# Read the contents of the file $AUTHFILE on the $AUTHSHARE share
+authfilebs=`echo "$AUTHFILE" | tr / '\\\\'`
+authinfo=`$SAMBAPREFIX/bin/smbclient "//$dcname/$AUTHSHARE" -I $dcip -d 0 -E -W "$DOMAINNAME" -c "get $authfilebs -" 2>/dev/null`
+echo "Contents of //$dcname/$AUTHSHARE/$AUTHFILE: $authinfo"
+
+# Allow for both \n and \r\n end-of-line termination
+[ "$authinfo" = "allow" -o "$authinfo" = "allow
" ] || exit 1
 exit 0
Index: squid/auth_modules/getpwnam/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/auth_modules/getpwnam/Attic/Makefile.in,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/auth_modules/getpwnam/Makefile.in	26 Jan 2000 03:23:09 -0000	1.1.1.1
+++ squid/auth_modules/getpwnam/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.1.1.1 2000/01/26 03:23:09 hno Exp $
+#  $Id: Makefile.in,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
Index: squid/cfgaux/config.guess
===================================================================
RCS file: /cvsroot/squid-sf//squid/cfgaux/Attic/config.guess,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/cfgaux/config.guess	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/cfgaux/config.guess	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -555,6 +555,9 @@
     news*:NEWS-OS:[56].*:*)
 	echo mips-sony-newsos${UNAME_RELEASE}
 	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo `arch`-apple-rhapsody${UNAME_RELEASE}
+	exit 0;;
     i?86:OS/2:*:*)
 	echo ${UNAME_MACHINE}-ibm-os2
 	exit 0 ;;
Index: squid/cfgaux/config.sub
===================================================================
RCS file: /cvsroot/squid-sf//squid/cfgaux/Attic/config.sub,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/cfgaux/config.sub	26 Jan 2000 03:23:09 -0000	1.1.1.2
+++ squid/cfgaux/config.sub	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -753,6 +753,9 @@
 	-xenix)
 		os=-xenix
 		;;
+	-rhapsody*)
+		os=-rhapsody
+		;;
 	-none)
 		;;
 	-os2)
Index: squid/doc/debug-sections.txt
===================================================================
RCS file: /cvsroot/squid-sf//squid/doc/debug-sections.txt,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/doc/debug-sections.txt	26 Jan 2000 03:21:46 -0000	1.1.1.1
+++ squid/doc/debug-sections.txt	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -84,3 +84,4 @@
 section 77    Delay Pools
 section 78    HTTP Connection Header
 section 79    HTTP Meter Header
+section 80    WCCP
Index: squid/doc/Programming-Guide/prog-guide.sgml
===================================================================
RCS file: /cvsroot/squid-sf//squid/doc/Programming-Guide/prog-guide.sgml,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/doc/Programming-Guide/prog-guide.sgml	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/doc/Programming-Guide/prog-guide.sgml	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid v1.2 Programmers Guide</title>
+<title>Squid Programmers Guide</title>
 <author>Duane Wessels, Squid Developers
 
 <abstract>
@@ -18,236 +18,184 @@
 <!-- %%%% Chapter : INTRODUCTION %%%% -->
 <sect>Introduction
 
-<P>
-The Squid source code has evolved more from empirical observation and
-tinkering, rather than a solid design process.  It carries a legacy of
-being ``touched'' by numerous individuals, each with somewhat different
-techniques and terminology.  
-
-<P>
-Squid is a single-process proxy server.  Every request is handled by
-the main process, with the exception of FTP.  However, Squid does not
-use a ``threads package'' such has Pthreads.  While this might be 
-easier to code, it suffers from portability and performance problems.
-Instead Squid maintains data structures and state information for
-each active request.
-
-<P>
-The code is often difficult to follow because there are no explicit
-state variables for the active requests.  Instead, thread execution
-progresses as a sequence of ``callback functions'' which get executed
-when I/O is ready to occur, or some other event has happened.  As
-a callback function completes, it is responsible for registering the
-next callback function for subsequent I/O.
-
-<P>
-Note there is only a pseudo-consistent naming scheme.  In most 
-cases functions are named like <tt/moduleFooBar()/.  However, there
-are also some functions named like <tt/module_foo_bar()/.
-
-<P>
-Note that the Squid source changes rapidly, and some parts of this
-document may become out-of-date.  If you find any inconsistencies, please
-feel free to notify
-<url url="mailto:squid-dev@nlanr.net"
-name="the Squid Developers">.
+	<P>
+	The Squid source code has evolved more from empirical
+	observation and tinkering, rather than a solid design
+	process.  It carries a legacy of being ``touched'' by
+	numerous individuals, each with somewhat different techniques
+	and terminology.
+
+	<P>
+	Squid is a single-process proxy server.  Every request is
+	handled by the main process, with the exception of FTP.
+	However, Squid does not use a ``threads package'' such has
+	Pthreads.  While this might be easier to code, it suffers
+	from portability and performance problems.  Instead Squid
+	maintains data structures and state information for each
+	active request.
+
+	<P>
+	The code is often difficult to follow because there are no
+	explicit state variables for the active requests.  Instead,
+	thread execution progresses as a sequence of ``callback
+	functions'' which get executed when I/O is ready to occur,
+	or some other event has happened.  As a callback function
+	completes, it is responsible for registering the next
+	callback function for subsequent I/O.
+
+	<P>
+	Note there is only a pseudo-consistent naming scheme.  In
+	most cases functions are named like <tt/moduleFooBar()/.
+	However, there are also some functions named like
+	<tt/module_foo_bar()/.
+
+	<P>
+	Note that the Squid source changes rapidly, and some parts
+	of this document may become out-of-date.  If you find any
+	inconsistencies, please feel free to notify <url
+	url="mailto:squid-dev@nlanr.net" name="the Squid Developers">.
 
 <sect1>Conventions
 
-<P>
-Function names and file names will be written in a courier font, such
-as <tt/store.c/ and <tt/storeRegister()/.  Data structures and their
-members will be written in an italicized font, such as <em/StoreEntry/.
+	<P>
+	Function names and file names will be written in a courier
+	font, such as <tt/store.c/ and <tt/storeRegister()/.  Data
+	structures and their members will be written in an italicized
+	font, such as <em/StoreEntry/.
 
-<sect1>The Big Picture
 
-<P>
+<sect>Overview of Squid Components
+
+	<P>
 Squid consists of the following major components
 
-<sect2>Client Side
+<sect1>Client Side
 
-<P>
-<em/Files:/ <tt/client_side.c/
-
-<P>
-    Here new client connections are accepted, parsed, and processed.
-    This is where we determine if the request is a cache HIT,
-    REFRESH, MISS, etc.  With HTTP/1.1 we may have multiple requests
-    from a single TCP connection.  Per-connection state information
-    is held in a data structure called <em/ConnStateData/.  Per-request
-    state information is stored in the <em/clientHttpRequest/ structure.
+	<P>
+	Here new client connections are accepted, parsed, and
+	processed.  This is where we determine if the request is
+	a cache HIT, REFRESH, MISS, etc.  With HTTP/1.1 we may have
+	multiple requests from a single TCP connection.  Per-connection
+	state information is held in a data structure called
+	<em/ConnStateData/.  Per-request state information is stored
+	in the <em/clientHttpRequest/ structure.
     
-<sect2>Server Side
-
-<P>
-<em/Files:/
-    <tt/proto.c/,
-    <tt/http.c/,
-    <tt/ftp.c/,
-    <tt/gopher.c/,
-    <tt/wais.c/,
-    <tt/ssl.c/,
-    <tt/pass.c/
-
-<P>
-    These routines are responsible for forwarding cache misses
-    to other servers, depending on the protocol.  Cache misses
-    may be forwarded to either origin servers, or other proxy caches.
-    Note that all requests (FTP, Gopher) to other
-    proxies are sent as HTTP requests.  
-    <tt/gopher.c/ is somewhat complex and gross because it must
-    convert from the Gopher protocol to HTTP.  Wais and Gopher don't
-    receive much attention because they comprise a relatively insignificant
-    portion of Internet traffic.
-
-<P>
-    <tt/ssl.c/ handles SSL requests (the CONNECT method) and
-    <tt/pass.c/ (``passthrough'') handles uncachable requests which
-    the cache doesn't really care about.   These two modules basically
-    pass bits back and forth between client and server.  Note they do
-    not use a <em/StoreEntry/ to do so.  About the only difference
-    between the two is that the SSL module sends a special ``connection
-    established'' message.
-
-<sect2>Storage Manager
-
-<P>
-<em/Files:/
-    <tt/store_clean.c/,
-    <tt/store_client.c/,
-    <tt/store_dir.c/,
-    <tt/store_key_md5.c/,
-    <tt/store_log.c/,
-    <tt/store_rebuild.c/,
-    <tt/store_swapin.c/,
-    <tt/store_swapmeta.c/,
-    <tt/store_swapout.c/,
-    <tt/store.c/
-
-<P>
-    The Storage Manager is the glue between client and server sides.
-    Every object saved in the cache is allocated a <em/StoreEntry/
-    structure.  While the object is being accessed, it also has a 
-    <em/MemObject/ structure.
-
-<P>
-    Squid can quickly locate cached objects because it keeps (in memory) a hash
-    table of all <em/StoreEntry/'s.  The keys for the hash
-    table are MD5 checksums of the objects URI.  In addition there is
-    also a doubly-linked list of <em/StoreEntry/'s used for the LRU
-    replacement algorithm.  When an entry is accessed, it is moved to
-    the head of the LRU list.  When Squid needs to replace cached objects,
-    it takes objects from the tail of the LRU list.
-
-<P>
-    Objects are saved to disk in a two-level directory structure.  For
-    each object the <em/StoreEntry/ includes a 4-byte <em/fileno/
-    field.  This file number is converted to a disk pathname by a
-    simple algorithm which evenly distributes the files across all 
-    cache directories.  A cache swap file consists of two parts:
-    the cache metadata, and the object data.  Note the object 
-    data includes the full HTTP reply---headers and body.  The HTTP
-    reply headers are not the same as the cache metadata.
-
-<P>
-    Client-side requests register themselves with a <em/StoreEntry/
-    to be notified when new data arrives.  Multiple clients may
-    receive data via a single <em/StoreEntry/.  For POST and
-    PUT request, this process works in reverse.  Server-side functions
-    are notified when additional data is read from the client.
-
-<sect2>Peer Selection
-
-<P>
-<em/Files:/
-	<tt/peer_select.c/
-
-<P>
-    These functions are responsible for selecting
-    one (or none) of the neighbor caches as the appropriate forwarding
-    location.
-
-<sect2>Access Control
-
-<P>
-<em/Files:/
-	<tt/acl.c/
+<sect1>Server Side
 
-<P>
-    These functions are responsible for allowing
-    or denying a request, based on a number of different parameters.
-    These parameters include the client's IP address, the hostname
-    of the requested resource, the request method, etc.
-    Some of the necessary information may not be immediately available,
-    for example the origin server's IP address.  In these cases, 
-    the ACL routines initiate lookups for the necessary information and
-    continues the access control checks when the information is
-    available.
-
-<sect2>Network Communication
-
-<P>
-<em/Files:/
-	<tt/comm.c/
-
-<P>
-    These are the routines for communicating over
-    TCP and UDP network sockets.  Here is where sockets are opened,
-    closed, read, and written.  In addition, note that the heart of
-    Squid (<tt/comm_select()/ or <tt/comm_poll()/) exists here, even
-    though it handles all file descriptors, not just network sockets.
-    These routines do not support queuing multiple
-    blocks of data for writing.  Consequently, a callback occurs
-    for every write request.
-
-<sect2>File/Disk I/O
-
-<P>
-<em/Files:/
-	<tt/disk.c/
-
-<P>
-    Routines for reading and writing disk files (and FIFOs).
-    Reasons for separating network and
-    disk I/O functions are partly historical, and partly because of
-    different behaviors.  For example, we don't worry about getting a
-    ``No space left on device'' error for network sockets.  The disk
-    I/O routines support queuing of multiple blocks for writing.
-    In some cases, it is possible to merge multiple blocks into
-    a single write request.  The write callback does not necessarily
-    occur for every write request.
-
-<sect2>Neighbors
-
-<P>
-<em/Files:/
-	<tt/neighbors.c/
-
-<P>
-    Maintains the list of neighbor caches.  Sends and receives 
-    ICP messages to neighbors.  Decides which neighbors to
-    query for a given request.  File: <tt/neighbors.c/.
-
-<sect2>IP/FQDN Cache
-
-<P>
-<em/Files:/
-	<tt/ipcache.c/, <tt/fqdncache.c/
-
-<P>
-    A cache of name-to-address and address-to-name lookups.  These are
-    hash tables keyed on the names and addresses.
-    <tt/ipcache_nbgethostbyname()/ and <tt/fqdncache_nbgethostbyaddr()/
-    implement the non-blocking lookups.  Files: <tt/ipcache.c/,
-    <tt/fqdncache.c/.
-
-<sect2>Cache Manager
+	<P>
+	These routines are responsible for forwarding cache misses
+	to other servers, depending on the protocol.  Cache misses
+	may be forwarded to either origin servers, or other proxy
+	caches.  Note that all requests (FTP, Gopher) to other
+	proxies are sent as HTTP requests.  <tt/gopher.c/ is somewhat
+	complex and gross because it must convert from the Gopher
+	protocol to HTTP.  Wais and Gopher don't receive much
+	attention because they comprise a relatively insignificant
+	portion of Internet traffic.
+
+<sect1>Storage Manager
+
+	<P>
+	The Storage Manager is the glue between client and server
+	sides.  Every object saved in the cache is allocated a
+	<em/StoreEntry/ structure.  While the object is being
+	accessed, it also has a <em/MemObject/ structure.
+
+	<P>
+	Squid can quickly locate cached objects because it keeps
+	(in memory) a hash table of all <em/StoreEntry/'s.  The
+	keys for the hash table are MD5 checksums of the objects
+	URI.  In addition there is also a doubly-linked list of
+	<em/StoreEntry/'s used for the LRU replacement algorithm.
+	When an entry is accessed, it is moved to the head of the
+	LRU list.  When Squid needs to replace cached objects, it
+	takes objects from the tail of the LRU list.
+
+	<P>
+	Objects are saved to disk in a two-level directory structure.
+	For each object the <em/StoreEntry/ includes a 4-byte
+	<em/fileno/ field.  This file number is converted to a disk
+	pathname by a simple algorithm which evenly distributes
+	the files across all cache directories.  A cache swap file
+	consists of two parts: the cache metadata, and the object
+	data.  Note the object data includes the full HTTP
+	reply---headers and body.  The HTTP reply headers are not
+	the same as the cache metadata.
+
+	<P>
+	Client-side requests register themselves with a <em/StoreEntry/
+	to be notified when new data arrives.  Multiple clients
+	may receive data via a single <em/StoreEntry/.  For POST
+	and PUT request, this process works in reverse.  Server-side
+	functions are notified when additional data is read from
+	the client.
+
+<sect1>Request Forwarding
+
+<sect1>Peer Selection
+
+	<P>
+	These functions are responsible for selecting one (or none)
+	of the neighbor caches as the appropriate forwarding
+	location.
+
+<sect1>Access Control
+
+	<P>
+	These functions are responsible for allowing or denying a
+	request, based on a number of different parameters.  These
+	parameters include the client's IP address, the hostname
+	of the requested resource, the request method, etc.  Some
+	of the necessary information may not be immediately available,
+	for example the origin server's IP address.  In these cases,
+	the ACL routines initiate lookups for the necessary
+	information and continues the access control checks when
+	the information is available.
+
+<sect1>Network Communication
+
+	<P>
+	These are the routines for communicating over TCP and UDP
+	network sockets.  Here is where sockets are opened, closed,
+	read, and written.  In addition, note that the heart of
+	Squid (<tt/comm_select()/ or <tt/comm_poll()/) exists here,
+	even though it handles all file descriptors, not just
+	network sockets.  These routines do not support queuing
+	multiple blocks of data for writing.  Consequently, a
+	callback occurs for every write request.
+
+<sect1>File/Disk I/O
+
+	<P>
+	Routines for reading and writing disk files (and FIFOs).
+	Reasons for separating network and disk I/O functions are
+	partly historical, and partly because of different behaviors.
+	For example, we don't worry about getting a ``No space left
+	on device'' error for network sockets.  The disk I/O routines
+	support queuing of multiple blocks for writing.  In some
+	cases, it is possible to merge multiple blocks into a single
+	write request.  The write callback does not necessarily
+	occur for every write request.
+
+<sect1>Neighbors
+
+	<P>
+	Maintains the list of neighbor caches.  Sends and receives
+	ICP messages to neighbors.  Decides which neighbors to
+	query for a given request.  File: <tt/neighbors.c/.
+
+<sect1>IP/FQDN Cache
+
+	<P>
+	A cache of name-to-address and address-to-name lookups.
+	These are hash tables keyed on the names and addresses.
+	<tt/ipcache_nbgethostbyname()/ and <tt/fqdncache_nbgethostbyaddr()/
+	implement the non-blocking lookups.  Files: <tt/ipcache.c/,
+	<tt/fqdncache.c/.
 
-<P>
-<em/Files:/
-	<tt/objcache.c/, <tt/stat.c/
+<sect1>Cache Manager
 
-<P>
+	<P>
 	This provides access to certain information needed by the
 	cache administrator.  A companion program, <em/cachemgr.cgi/
 	can be used to make this information available via a Web
@@ -260,13 +208,9 @@
 	to information.  It does not provide a method for configuring
 	Squid while it is running.
 
-<sect2>Network Measurement Database
-
-<P>
-<em/Files:/
-	<tt/net_db.c/
+<sect1>Network Measurement Database
 
-<P>
+	<P>
 	In a number of situation, Squid finds it useful to know the
 	estimated network round-trip time (RTT) between itself and
 	origin servers.  A particularly useful is example is
@@ -283,13 +227,9 @@
 	aggregation is used to reduce the overall database size.  File:
 	<tt/net_db.c/.
 
-<sect2>Redirectors
+<sect1>Redirectors
 
-<P>
-<em/Files:/
-	<tt/redirect.c/
-
-<P>
+	<P>
 	Squid has the ability to rewrite requests from clients.  After
 	checking the access controls, but before checking for cache hits,
 	requested URLs may optionally be written to an external
@@ -298,53 +238,27 @@
 	Common applications for this feature are extended access controls
 	and local mirroring.  File: <tt/redirect.c/.
 
-<sect2>Autonomous System Numbers
+<sect1>Autonomous System Numbers
 
-<P>
-<em/Files:/
-	<tt/asn.c/
-
-<P>
+	<P>
 	Squid supports Autonomous System (AS) numbers as another 
 	access control element.  The routines in <tt/asn.c/
 	query databases which map AS numbers into lists of CIDR
 	prefixes.  These results are stored in a radix tree which
 	allows fast searching of the AS number for a given IP address.
-	
-<sect2>Asynchronous I/O Operations
-
-<P>
-<em/Files:/
-	<tt/async_io.c/, <tt/aiops.c/
-
-<P>
-	These routines in <tt/async_io.c/ and <tt/aiops.c/ 
-	implement blocking disk operations in a set of thread (child)
-	processes.
 
-<sect2>Configuration File Parsing
-
-<P>
-<em/Files:/
-	<tt/cf.data.pre/,
-	<tt/cf_gen.c/,
-	<tt/cf_parser.c/,
-	<tt/cache_cf.c/
+<sect1>Configuration File Parsing
 
-<P>
+	<P>
 	The primary configuration file specification is in the file
 	<tt/cf.data.pre/.  A simple utility program, <tt/cf_gen/,
 	reads the <tt/cf.data.pre/ file and generates <tt/cf_parser.c/
 	and <tt/squid.conf/.  <tt/cf_parser.c/ is included directly
 	into <tt/cache_cf.c/ at compile time.
 
-<sect2>Callback Data Database
-
-<P>
-<em/Files:/
-	<tt/cbdata.c/
+<sect1>Callback Data Database
 
-<P>
+	<P>
 	Squid's extensive use of callback functions makes it very
 	susceptible to memory access errors.  Care must be taken
 	so that the <tt/callback_data/ memory is still valid when
@@ -352,13 +266,9 @@
 	provide a uniform method for managing callback data memory,
 	canceling callbacks, and preventing erroneous memory accesses.
 
-<sect2>Debugging
-
-<P>
-<em/Files:/
-	<tt/debug.c/
+<sect1>Debugging
 
-<P>
+	<P>
 	Squid includes extensive debugging statements to assist in
 	tracking down bugs and strange behavior.  Every debug statement
 	is assigned a section and level.  Usually, every debug statement
@@ -373,70 +283,49 @@
 	probably sounds more complicated than it really is.
 	File: <em/debug.c/.  Note that <tt/debug()/ itself is a macro.
 
-<sect2>Error Generation
+<sect1>Error Generation
 
-<P>
-<em/Files:/
-	<tt/errorpage.c/
-
-<P>
+	<P>
 	The routines in <tt/errorpage.c/ generate error messages from
 	a template file and specific request parameters.  This allows
 	for customized error messages and multilingual support.
 
-<sect2>Event Queue
+<sect1>Event Queue
 
-<P>
-<em/Files:/
-	<tt/event.c/
-
-<P>
+	<P>
 	The routines in <tt/event.c/ maintain a linked-list event
 	queue for functions to be executed at a future time.  The
 	event queue is used for periodic functions such as performing
 	cache replacement, cleaning swap directories, as well as one-time
 	functions such as ICP query timeouts.
-	
-<sect2>Filedescriptor Management
-<P>
-<em/Files:/
-	<tt/fd.c/
 
-<P>
+<sect1>Filedescriptor Management
+
+	<P>
 	Here we track the number of filedescriptors in use, and the
 	number of bytes which has been read from or written to each
 	file descriptor.
 
 
-<sect2>Hashtable Support
-<P>
-<em/Files:/
-	<tt/hash.c/
+<sect1>Hashtable Support
 
-<P>
+	<P>
 	These routines implement generic hash tables.  A hash table
 	is created with a function for hashing the key values, and a
 	function for comparing the key values.
 
-<sect2>HTTP Anonymization
-<P>
-<em/Files:/
-	<tt/http-anon.c/
+<sect1>HTTP Anonymization
 
-<P>
+	<P>
 	These routines support anonymizing of HTTP requests leaving
 	the cache.  Either specific request headers will be removed
 	(the ``standard'' mode), or only specific request headers
 	will be allowed (the ``paranoid'' mode).
 
 
-<sect2>Internet Cache Protocol
-<P>
-<em/Files:/
-	<tt/icp_v2.c/,
-	<tt/icp_v3.c/
+<sect1>Internet Cache Protocol
 
-<P>
+	<P>
 	Here we implement the Internet Cache Protocol.  This 
 	protocol is documented in the RFC 2186 and RFC 2187.
 	The bulk of code is in the <tt/icp_v2.c/ file.  The 
@@ -445,23 +334,17 @@
 	a different version number and a slightly different message
 	format.
 
-<sect2>Ident Lookups
-<P>
-<em/Files:/
-	<tt/ident.c/
+<sect1>Ident Lookups
 
-<P>
+	<P>
 	These routines support RFC 931 ``Ident'' lookups.   An ident
 	server running on a host will report the user name associated
 	with a connected TCP socket.  Some sites use this facility for
 	access control and logging purposes.
 
-<sect2>Memory Management
-<P>
-<em/Files:/
-	<tt/mem.c/
+<sect1>Memory Management
 
-<P>
+	<P>
 	These routines allocate and manage pools of memory for
 	frequently-used data structures.  When the <em/memory_pools/
 	configuration option is enabled, unused memory is not actually
@@ -469,23 +352,17 @@
 	in more efficient use of memory at the expense of a larger
 	process size.
 
-<sect2>Multicast Support
-<P>
-<em/Files:/
-	<tt/multicast.c/
+<sect1>Multicast Support
 
-<P>
+	<P>
 	Currently, multicast is only used for ICP queries.   The
 	routines in this file implement joining a UDP 
 	socket to a multicast group (or groups), and setting
 	the multicast TTL value on outgoing packets.
 
-<sect2>Persistent Server Connections
-<P>
-<em/Files:/
-	<tt/pconn.c/
+<sect1>Persistent Server Connections
 
-<P>
+	<P>
 	These routines manage idle, persistent HTTP connections
 	to origin servers and neighbor caches.  Idle sockets
 	are indexed in a hash table by their socket address
@@ -494,68 +371,50 @@
 	15 seconds.  After 15 seconds, idle socket connections
 	are closed.
 
-<sect2>Refresh Rules
-
-<P>
-<em/Files:/
-	<tt/refresh.c/
+<sect1>Refresh Rules
 
-<P>
+	<P>
 	These routines decide wether a cached object is stale or fresh,
 	based on the <em/refresh_pattern/ configuration options.
 	If an object is fresh, it can be returned as a cache hit.
 	If it is stale, then it must be revalidated with an	
 	If-Modified-Since request.
 
-<sect2>SNMP Support
-<P>
-<em/Files:/
-	<tt/snmp.c/,
-	<tt/snmp_agent.c/,
-	<tt/snmp_config.c/,
-	<tt/snmp_vars.c/
+<sect1>SNMP Support
 
-<P>
+	<P>
 	These routines implement SNMP for Squid.  At the present time,
 	we have made almost all of the cachemgr information available
 	via SNMP.
 
-<sect2>URN Support
-<P>
-<em/Files:/
-	<tt/urn.c/
+<sect1>URN Support
 
-<P>
-We are experimenting with URN support in Squid version 1.2.  Note,
-we're not talking full-blown generic URN's here. This is primarily
-targeted towards using URN's as an smart way of handling lists of
-mirror sites.  For more details, please see
-<url	url="http://squid.nlanr.net/Squid/urn-support.html"
+	<P>
+	We are experimenting with URN support in Squid version 1.2.
+	Note, we're not talking full-blown generic URN's here. This
+	is primarily targeted towards using URN's as an smart way
+	of handling lists of mirror sites.  For more details, please
+	see <url        url="http://squid.nlanr.net/Squid/urn-support.html"
 	name="URN support in Squid">.
 
 
-<sect1>External Programs
+<sect>External Programs
 
-<sect2>dnsserver
-<P>
-<em/Files:/
-	<tt/dnsserver.c/
+<sect1>dnsserver
 
-<P>
-    Because the standard <tt/gethostbyname(3)/ library call blocks,
-    Squid must use external processes to actually make these calls.
-    Typically there will be ten <tt/dnsserver/ processes spawned from
-    Squid.  Communication occurs via TCP sockets bound to the loopback
-    interface.  The functions in <tt/dns.c/ are primarily concerned
-    with starting and stopping the dnsservers.  Reading and writing to
-    and from the dnsservers occurs in the IP and FQDN cache modules.
+	<P>
+	Because the standard <tt/gethostbyname(3)/ library call
+	blocks, Squid must use external processes to actually make
+	these calls.  Typically there will be ten <tt/dnsserver/
+	processes spawned from Squid.  Communication occurs via
+	TCP sockets bound to the loopback interface.  The functions
+	in <tt/dns.c/ are primarily concerned with starting and
+	stopping the dnsservers.  Reading and writing to and from
+	the dnsservers occurs in the IP and FQDN cache modules.
 
-<sect2>pinger
-<P>
-<em/Files:/
-	<tt/pinger.c/
+<sect1>pinger
 
-<P>
+	<P>
 	Although it would be possible for Squid to send and receive
 	ICMP messages directly, we use an external process for
 	two important reasons:
@@ -568,141 +427,143 @@
 	we prefer to have the smaller and simpler <em/pinger/
 	program installed with setuid permissions.
 	</enum>
-	
-<sect2>unlinkd
-<P>
-<em/Files:/
-	<tt/unlinkd.c/
 
-<P>
+<sect1>unlinkd
+
+	<P>
 	The <tt/unlink(2)/ system call can cause a process to block
 	for a significant amount of time.  Therefore we do not want
 	to make unlink() calls from Squid.  Instead we pass them
 	to this external process.
 
-<sect2>redirector
-
-<P>
-<em/Files:/
-	user-developed
+<sect1>redirector
 
-<P>
+	<P>
 	A redirector process reads URLs on stdin and writes (possibly
 	changed) URLs on stdout.  It is implemented as an external
 	process to maximize flexibility.
 
-<sect1>Sequence of a Typical Request
+<sect>Flow of a Typical Request
 
-<P>
-<enum>
-<item>
-A client connection is accepted by the <em/client-side/.  The HTTP request
-is parsed.
-
-<item>
-The access controls are checked.  The client-side builds an
-ACL state data structure and registers a callback function
-for notification when access control checking is completed.
-
-<item>
-After the access controls have been verified, the client-side looks for
-the requested object in the cache.  If is a cache hit, then the
-client-side registers its interest in the <em/StoreEntry/.  Otherwise,
-Squid needs to forward the request, perhaps with an If-Modified-Since
-header.
-
-<item>
-The request-forwarding process begins with <tt/protoDispatch/.
-This function begins the peer selection procedure, which may
-involve sending ICP queries and receiving ICP replies.  The peer
-selection procedure also involves checking configuration
-options such as <em/never_direct/ and <em/always_direct/.
-
-<item>
-When the ICP replies (if any) have been processed, we end up
-at <em/protoStart/.  This function calls an appropriate 
-protocol-specific function for forwarding the request.  Here we
-will assume it is an HTTP request.
-
-<item>
-The HTTP module first opens a connection to the origin server
-or cache peer.  If there is no idle persistent socket available,
-a new connection request is given to the Network Communication
-module with a callback function.  The <tt/comm.c/ routines
-may try establishing a connection multiple times before giving up.
-
-<item>
-When a TCP connection has been established, HTTP builds a request
-buffer and submits it for writing on the socket.  It then registers
-a read handler to receive and process the HTTP reply.
-
-<item>
-As the reply is initially received, the HTTP reply headers are
-parsed and placed into a reply data structure.  As reply data
-is read, it is appended to the <em/StoreEntry/.  Every time data
-is appended to the <em/StoreEntry/, the client-side is 
-notified of the new data via a callback function.
-
-<item>
-As the client-side is notified of new data, it copies the data
-from the StoreEntry and submits it for writing on the client socket.
-
-<item>
-As data is appended to the <em/StoreEntry/, and the client(s)
-read it, the data may be submitted for writing to disk.
-
-<item>
-When the HTTP module finishes reading the reply from the upstream
-server, it marks the <em/StoreEntry/ as ``complete.''  The server
-socket is either closed or given to the persistent connection pool
-for future use.
-
-<item>
-When the client-side has written all of the object data, it unregisters
-itself from the <em/StoreEntry/.  At the same time it either waits for
-another request from the client, or closes the client connection.
+	<P>
+	<enum>
+	<item>
+	A client connection is accepted by the <em/client-side/.
+	The HTTP request is parsed.
+
+	<item>
+	The access controls are checked.  The client-side builds
+	an ACL state data structure and registers a callback function
+	for notification when access control checking is completed.
+
+	<item>
+	After the access controls have been verified, the client-side
+	looks for the requested object in the cache.  If is a cache
+	hit, then the client-side registers its interest in the
+	<em/StoreEntry/.  Otherwise, Squid needs to forward the
+	request, perhaps with an If-Modified-Since header.
+
+	<item>
+	The request-forwarding process begins with <tt/protoDispatch/.
+	This function begins the peer selection procedure, which
+	may involve sending ICP queries and receiving ICP replies.
+	The peer selection procedure also involves checking
+	configuration options such as <em/never_direct/ and
+	<em/always_direct/.
+
+	<item>
+	When the ICP replies (if any) have been processed, we end
+	up at <em/protoStart/.  This function calls an appropriate
+	protocol-specific function for forwarding the request.
+	Here we will assume it is an HTTP request.
+
+	<item>
+	The HTTP module first opens a connection to the origin
+	server or cache peer.  If there is no idle persistent socket
+	available, a new connection request is given to the Network
+	Communication module with a callback function.  The
+	<tt/comm.c/ routines may try establishing a connection
+	multiple times before giving up.
+
+	<item>
+	When a TCP connection has been established, HTTP builds a
+	request buffer and submits it for writing on the socket.
+	It then registers a read handler to receive and process
+	the HTTP reply.
+
+	<item>
+	As the reply is initially received, the HTTP reply headers
+	are parsed and placed into a reply data structure.  As
+	reply data is read, it is appended to the <em/StoreEntry/.
+	Every time data is appended to the <em/StoreEntry/, the
+	client-side is notified of the new data via a callback
+	function.
+
+	<item>
+	As the client-side is notified of new data, it copies the
+	data from the StoreEntry and submits it for writing on the
+	client socket.
+
+	<item>
+	As data is appended to the <em/StoreEntry/, and the client(s)
+	read it, the data may be submitted for writing to disk.
+
+	<item>
+	When the HTTP module finishes reading the reply from the
+	upstream server, it marks the <em/StoreEntry/ as ``complete.''
+	The server socket is either closed or given to the persistent
+	connection pool for future use.
+
+	<item>
+	When the client-side has written all of the object data,
+	it unregisters itself from the <em/StoreEntry/.  At the
+	same time it either waits for another request from the
+	client, or closes the client connection.
 
-</enum>
+	</enum>
 
-<!-- %%%% Chapter : MAIN LOOP %%%% -->
-<sect>The Main Loop: <tt/comm_select()/
+<sect>Callback Functions
 
-<P>
-At the core of Squid is the <tt/select(2)/ system call.  Squid uses
-<tt/select()/ or <tt/poll(2)/ to process I/O on all open file descriptors.
-Hereafter we'll only use ``select'' to refer generically to either system call.
+<sect>The Main Loop: <tt/comm_select()/
 
-<P>
-The <tt/select()/ and <tt/poll()/ system calls work by waiting for
-I/O events on a set of file descriptors.  Squid only checks for
-<em/read/ and <em/write/ events. Squid knows that it should
-check for reading or writing when there
-is a read or write handler registered for a given file descriptor.  
-Handler functions are registered with the <tt/commSetSelect/ function.
-For example:
+	<P>
+	At the core of Squid is the <tt/select(2)/ system call.
+	Squid uses <tt/select()/ or <tt/poll(2)/ to process I/O on
+	all open file descriptors.  Hereafter we'll only use
+	``select'' to refer generically to either system call.
+
+	<P>
+	The <tt/select()/ and <tt/poll()/ system calls work by
+	waiting for I/O events on a set of file descriptors.  Squid
+	only checks for <em/read/ and <em/write/ events. Squid
+	knows that it should check for reading or writing when
+	there is a read or write handler registered for a given
+	file descriptor.  Handler functions are registered with
+	the <tt/commSetSelect/ function.  For example:
 <verb>
 	commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0);
 </verb>
-In this example, <em/fd/ is a TCP socket to a client connection.
-When there is data to be read from the socket, then the select loop
-will execute
+	In this example, <em/fd/ is a TCP socket to a client
+	connection.  When there is data to be read from the socket,
+	then the select loop will execute
 <verb>
 	clientReadRequest(fd, conn);
 </verb>
 
-<P>
-The I/O handlers are reset every time they are called.  In other words,
-a handler function must re-register itself with <tt/commSetSelect/
-if it wants to continue reading or writing on a file descriptor.
-The I/O handler may be canceled before being called by providing
-NULL arguments, e.g.:
+	<P>
+	The I/O handlers are reset every time they are called.  In
+	other words, a handler function must re-register itself
+	with <tt/commSetSelect/ if it wants to continue reading or
+	writing on a file descriptor.  The I/O handler may be
+	canceled before being called by providing NULL arguments,
+	e.g.:
 <verb>
 	commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
 </verb>
 
-<P>
-These I/O handlers (and others) and their associated callback data
-pointers are saved in the <em/fde/ data structure:
+	<P>
+	These I/O handlers (and others) and their associated callback
+	data pointers are saved in the <em/fde/ data structure:
 <verb>
 	struct _fde {
 		...
@@ -715,81 +576,558 @@
 		void *defer_data;
 	};
 </verb>
-<em/read_handler/ and <em/write_handler/ are called when the file
-descriptor is ready for reading or writing, respectively.  
-The <em/close_handler/ is called when the filedescriptor
-is closed.   The <em/close_handler/ is actually a linked list
-of callback functions to be called.
-
-<P>
-In some situations we want to defer reading from a filedescriptor,
-even though it has data for us to read.  This may be the case
-when data arrives from the server-side faster than it can 
-be written to the client-side.
-Before adding a filedescriptor to the ``read set'' for select,
-we call <em/defer_check/ (if it is non-NULL).  If <em/defer_check/
-returns 1, then we skip the filedescriptor for that time through
-the select loop.
+	<em/read_handler/ and <em/write_handler/ are called when
+	the file descriptor is ready for reading or writing,
+	respectively.  The <em/close_handler/ is called when the
+	filedescriptor is closed.   The <em/close_handler/ is
+	actually a linked list of callback functions to be called.
+
+	<P>
+	In some situations we want to defer reading from a
+	filedescriptor, even though it has data for us to read.
+	This may be the case when data arrives from the server-side
+	faster than it can be written to the client-side.  Before
+	adding a filedescriptor to the ``read set'' for select, we
+	call <em/defer_check/ (if it is non-NULL).  If <em/defer_check/
+	returns 1, then we skip the filedescriptor for that time
+	through the select loop.
 
 
 
-<P>
-These handlers are stored in the <em/FD_ENTRY/ structure as defined in
-<tt/comm.h/.  <tt/fd_table[]/ is the global array of <em/FD_ENTRY/
-structures.  The handler functions are of type <em/PF/, which is a
-typedef:
+	<P>
+	These handlers are stored in the <em/FD_ENTRY/ structure
+	as defined in <tt/comm.h/.  <tt/fd_table[]/ is the global
+	array of <em/FD_ENTRY/ structures.  The handler functions
+	are of type <em/PF/, which is a typedef:
 <verb>
     typedef void (*PF) (int, void *);
 </verb>
-The close handler is really a linked list of handler functions.
-Each handler also has an associated pointer <tt/(void *data)/ to
-some kind of data structure.
+	The close handler is really a linked list of handler
+	functions.  Each handler also has an associated pointer
+	<tt/(void *data)/ to some kind of data structure.
+
+	<P>
+	<tt/comm_select()/ is the function which issues the select()
+	system call.  It scans the entire <tt/fd_table[]/ array
+	looking for handler functions.  Each file descriptor with
+	a read handler will be set in the <tt/fd_set/ read bitmask.
+	Similarly, write handlers are scanned and bits set for the
+	write bitmask.  <tt/select()/ is then called, and the return
+	read and write bitmasks are scanned for descriptors with
+	pending I/O.  For each ready descriptor, the handler is
+	called.  Note that the handler is cleared from the
+	<em/FD_ENTRY/ before it is called.
+
+	<P>
+	After each handler is called, <tt/comm_select_incoming()/
+	is called to process new HTTP and ICP requests.
+
+	<P>
+	Typical read handlers are
+	<tt/httpReadReply()/,
+	<tt/diskHandleRead()/,
+	<tt/icpHandleUdp()/,
+	and <tt/ipcache_dnsHandleRead()/.
+	Typical write handlers are
+	<tt/commHandleWrite()/,
+	<tt/diskHandleWrite()/,
+	and <tt/icpUdpReply()/.
+	The handler function is set with <tt/commSetSelect()/, with the
+	exception of the close handlers, which are set with
+	<tt/comm_add_close_handler()/.
+
+	<P>
+	The close handlers are normally called from <tt/comm_close()/.
+	The job of the close handlers is to deallocate data structures
+	associated with the file descriptor.  For this reason
+	<tt/comm_close()/ must normally be the last function in a
+	sequence to prevent accessing just-freed memory.
+
+	<P>
+	The timeout and lifetime handlers are called for file
+	descriptors which have been idle for too long.  They are
+	further discussed in a following chapter.
 
-<P>
-<tt/comm_select()/ is the function which issues the select() system
-call.  It scans the entire <tt/fd_table[]/ array looking for handler
-functions.  Each file descriptor with a read handler will be set in
-the <tt/fd_set/ read bitmask.  Similarly, write handlers are scanned and
-bits set for the write bitmask.  <tt/select()/ is then called, and the
-return read and write bitmasks are scanned for descriptors with pending
-I/O.  For each ready descriptor, the handler is called.  Note that
-the handler is cleared from the <em/FD_ENTRY/ before it is called.
+<!-- %%%% Chapter : CLIENT REQUEST PROCESSING %%%% -->
+<sect>Processing Client Requests
 
-<P>
-After each handler is called, <tt/comm_select_incoming()/ is
-called to process new HTTP and ICP requests.
+<!-- %%%% Chapter : STORAGE MANAGER %%%% -->
+<sect>Storage Manager
 
-<P>
-Typical read handlers are
-<tt/httpReadReply()/,
-<tt/diskHandleRead()/,
-<tt/icpHandleUdp()/,
-and <tt/ipcache_dnsHandleRead()/.
-Typical write handlers are
-<tt/commHandleWrite()/,
-<tt/diskHandleWrite()/,
-and <tt/icpUdpReply()/.
-The handler function is set with <tt/commSetSelect()/, with the
-exception of the close handlers, which are set with
-<tt/comm_add_close_handler()/.
+<!-- %%%% Chapter : FILESYSTEM INTERFACE %%%% -->
+<sect>Filesystem Interface
 
-<P>
-The close handlers are normally called from <tt/comm_close()/.  
-The job of the close handlers is to deallocate data structures 
-associated with the file descriptor.  For this reason <tt/comm_close()/
-must normally be the last function in a sequence to prevent accessing
-just-freed memory.
+<sect1>Introduction
 
-<P>
-The timeout and lifetime handlers are called for file descriptors which
-have been idle for too long.  They are further discussed in a following 
-chapter.
+	<P>
+	Traditionally, Squid has always used the Unix filesystem (UFS)
+	to store cache objects on disk.  Over the years, the
+	poor performance of UFS has become very obvious.  In most
+	cases, UFS limits Squid to about 30-50 requests per second.
+	Our work indicates that the poor performance is mostly
+	due to the synchronous nature of <tt/open()/ and <tt/unlink()/
+	system calls, and perhaps thrashing of inode/buffer caches.
+
+	<P>
+	We want to try out our own, customized filesystems with Squid.
+	In order to do that, we need a well-defined interface
+	for the bits of Squid that access the permanent storage
+	devices.
+
+<sect1>The Interface
+
+<sect2>Data Structures
+
+<sect3><em/storeIOState/
+
+	<P>
+	Every cache object that is ``opened'' for reading or writing
+	will have a <em/storeIOState/ data structure associated with
+	it.  Currently, this structure looks like:
+<verb>
+        struct _storeIOState {
+            sfileno swap_file_number;
+            mode_t mode;
+            size_t st_size;             /* do stat(2) after read open */
+            off_t offset;               /* current offset pointer */
+            STIOCB *callback;
+            void *callback_data;
+            struct {
+                STRCB *callback;
+                void *callback_data;
+            } read;
+            struct {
+                unsigned int closing:1; /* debugging aid */
+            } flags;
+            union {
+                struct {
+                    int fd;
+                    struct {
+                        unsigned int close_request:1;
+                        unsigned int reading:1;
+                        unsigned int writing:1;
+                    } flags;
+                } ufs;
+            } type;
+        };
+</verb>
 
-<!-- %%%% Chapter : CLIENT REQUEST PROCESSING %%%% -->
-<sect>Processing Client Requests
+	<em/swap_file_number/ is the 32-bit swap file number for the
+	object, taken from the <em/StoreEntry/.
+
+	<em/mode/ is either O_RDONLY or O_WRONLY.
+
+	<em/offset/ represents the file (byte) offset after the
+	last operation completed.  For example, after a read operation,
+	<em/offset/ must be incremented by the number of bytes read.
+	The same goes for write operations.  This means that the
+	filesystem layer needs explicit (callback) notification
+	for writes.  It is wrong to increment <em/offset/ before
+	an I/O operation has been known to succeed.
+
+	<em/st_size/ is filled in with the object's on-disk size
+	after an object is opened for reading.  This allows
+	the upper layers to double-check that the disk object
+	actually belongs to the StoreEntry.
+
+	Note that there are two callback functions.  The first,
+	<em/callback/, of type <em/STIOCB/ (store I/O callback),
+	is callback for the <em/storeIOState/ as a whole.  This
+	callback is used to indicate success or failure of accessing
+	the object, whether its for reading or writing.
+	There are no callbacks for open and write operations,
+	unless they fail.
+
+	The second, <em/read.callback/, of type <em/STRCB/ (store
+	read callback) is used for every read operation.
+
+	The ugly union is used to hold filesystem-specific state
+	information.
+
+	<em/storeIOState/ structures are allocated by calling
+	<tt/storeOpen()/, and will be deallocated by the
+	filesystem layer after
+	<tt/storeClose()/ is called.
+
+<sect2>External Functions
+
+<sect3>Object I/O
+
+	<P>
+	These functions all relate to per-object I/O tasks: opening,
+	closing, reading, writing, and unlinking objects on disk.
+	These functions can all be found in <tt/store_io.c/.
+
+	<P>
+	Note that the underlying storage system functions are
+	accessed through function pointers, kept in the
+	<em/SwapDir/ structure:
+<verb>
+    struct _SwapDir {
+	....
+        struct {
+            STOBJOPEN *open;
+            STOBJCLOSE *close;
+            STOBJREAD *read;
+            STOBJWRITE *write;
+            STOBJUNLINK *unlink;
+        } obj;
+	....
+    };
+</verb>
+
+	<P>
+	Thus, a storage system must do something like this
+	when initializing its <em/SwapDir/ structure:
+<verb>
+            SwapDir->obj.open = storeFooOpen;
+            SwapDir->obj.close = storeFooClose;
+            SwapDir->obj.read = storeFooRead;
+            SwapDir->obj.write = storeFooWrite;
+            SwapDir->obj.unlink = storeFooUnlink;
+</verb>
+
+<sect4><tt/storeOpen()/
+
+	<P>
+<verb>
+	storeIOState *
+	storeOpen(sfileno f, mode_t mode, STIOCB *callback, void *callback_data)
+</verb>
+
+	<P>
+	<tt/storeOpen()/
+	submits a request to open a cache object for reading or writing.
+	<tt/f/ is the 32-bit swap file number of the cached object.
+	<tt/mode/ should be either <tt/O_RDONLY/ or <tt/O_WRONLY/.
+
+	<P>
+	<tt/callback/ is a function that will be called either when
+	an error is encountered, or when the object is closed (by
+	calling <tt/storeClose()/).  If the open request is
+	successful, there is no callback.  The calling module must
+	assume the open request will succeed, and may begin reading
+	or writing immediately.
+
+	<P>
+	<tt/storeOpen()/ may return NULL if the requested object
+	can not be openeed.  In this case the <tt/callback/ function
+	will not be called.
+
+<sect4><tt/storeClose()/
+
+	<P>
+<verb>
+	void
+	storeClose(storeIOState *sio)
+</verb>
+
+	<P>
+	<tt/storeClose()/
+	submits a request to close the cache object.  It is safe to request
+	a close even if there are read or write operations pending.
+	When the underlying filesystem actually closes the object,
+	the <em/STIOCB/ callback (registered with <tt/storeOpen()/) will
+	be called.
+
+<sect4><tt/storeRead()/
+
+	<P>
+<verb>
+	void
+	storeRead(storeIOState *sio, char *buf, size_t size, off_t offset, STRCB *callback, void *callback_data)
+</verb>
+
+	<P>
+	<tt/storeRead()/ is more complicated than the other functions
+	because it requires its own callback function to notify the
+	caller when the requested data has actually been read. 
+	<em/buf/ must be a valid memory buffer of at least <em/size/
+	bytes.  <em/offset/ specifies the byte offset where the
+	read should begin.  Note that with the Swap Meta Headers
+	prepended to each cache object, this offset does not equal
+	the offset into the actual object data.
+
+	<P>
+	The caller is responsible for allocating and freeing <em/buf/
+
+<sect4><tt/storeWrite()/
+
+	<P>
+<verb>
+	void
+	storeWrite(storeIOState *sio, char *buf, size_t size, off_t offset, FREE *free_func)
+</verb>
+
+	<P>
+	<tt/storeWrite()/ submits a request to write a block
+	of data to the disk store.  
+	The caller is responsible for allocating <em/buf/, but since
+	there is no per-write callback, this memory must be freed by
+	the lower filesystem implementation.  Therefore, the caller
+	must specify the <em/free_func/ to be used to deallocate
+	the memory.
+
+	<P>
+	If a write operation fails, the filesystem layer notifies the
+	calling module by calling the <em/STIOCB/ callback with an
+	error status code.
+
+<sect4><tt/storeUnlink()/
+
+	<P>
+<verb>
+	void
+	storeUnlink(sfileno f)
+</verb>
+
+	<P>
+	<tt/storeUnlink()/ removes the cached object from the disk
+	store.  There is no callback function, and the object
+	does not need to be opened first.  The filesystem
+	layer will remove the object if it exists on the disk.
+
+<sect4><tt/storeOffset()/
+
+	<P>
+<verb>
+	off_t
+	storeOffset(storeIOState *sio)
+</verb>
+
+	<P>
+	Returns the current byte-offset of the cache object on
+	disk.  For read-objects, this is the offset after the last
+	successful disk read operation.  For write-objects, it is
+	the offset of the last successful disk write operation.
+
+<sect4><em/STIOCB/ callback
+
+	<P>
+<verb>
+	void
+	stiocb(void *data, int errorflag, storeIOState *sio)
+</verb>
+
+	<P>
+	The <em/stiocb/ function is passed as a parameter to
+	<tt/storeOpen()/.  The filesystem layer calls <em/stiocb/
+	either when an I/O error occurs, or when the disk
+	object is closed.
+
+	<P>
+	<em/errorflag/ is one of the following:
+<verb>
+	#define DISK_OK                   (0)
+	#define DISK_ERROR               (-1)
+	#define DISK_EOF                 (-2)
+	#define DISK_NO_SPACE_LEFT       (-6)
+</verb>
+
+	<P>
+	Once the The <em/stiocb/ function has been called,
+	the <em/sio/ structure should not be accessed further.
+
+<sect4><em/STRCB/ callback
+
+	<P>
+<verb>
+	void
+	strcb(void *data, const char *buf, size_t len)
+</verb>
+
+	<P>
+	The <em/strcb/ function is passed as a parameter to
+	<tt/storeRead()/.  The filesystem layer calls <em/strcb/
+	after a block of data has been read from the disk and placed
+	into <em/buf/.  <em/len/ indicates how many bytes were
+	placed into <em/buf/.  The <em/strcb/ function is only
+	called if the read operation is successful.  If it fails,
+	then the <em/STIOCB/ callback will be called instead.
+
+<sect3>Config file parsing
+
+	<P>
+	There are three functions relating to the Squid configuration
+	file: parsing, dumping, and freeing.
+
+	<P>
+	The parse function is called at startup, and during a reconfigure,
+	for a <em/cache_dir/ line.  The first keyword after the <em/cache_dir/
+	keyword will be a filesystem type (such as "ufs").  A switch
+	statement in <tt/parse_cachedir/ will call the appropriate
+	filesystem-dependent parsing function.  The parsing function
+	may use <tt/strtok()/ to continue reading keywords after the
+	filesystem type on the <em/cache_dir/ line.
+
+
+	<P>
+	The ``dump'' function is used to output a configuration
+	file from the in-memory configuration structure.  It is
+	called with a <em/SwapDir/ argument, and must append one
+	line to the <em/StoreEntry/ that is holding the configuration
+	file being generated.
+
+	<P>
+	The free function is called during a reconfigure (and at
+	exit) to free up (or un-initialize) any memory or structures
+	associated with the configuration line.  The <em/SwapDir/
+	structure includes common and private sections.  The
+	<tt/free_cachedir()/ function will handle freeing anything
+	in the common section, and relies on a filesystem-dependent
+	function to free, or un-initialize private members.
+
+<sect3>Filesystem Startup, Initialization, and State Logging
+
+	<P>
+	These functions deal with initializing, state
+	logging, and related tasks for a squid storage system.
+	These functions are used (called) in <tt/store_dir.c/.
+
+	<P>
+	Each storage system must provide the functions described
+	in this section, although it may be a no-op (null) function
+	that does nothing.  Each function is accessed through a
+	function pointer stored in the <em/SwapDir/ structure:
+
+<verb>
+    struct _SwapDir {
+        ...
+        STINIT *init;
+        STNEWFS *newfs;
+        struct {
+            STLOGOPEN *open;
+            STLOGCLOSE *close;
+            STLOGWRITE *write;
+            struct {
+                STLOGCLEANOPEN *open;
+                STLOGCLEANWRITE *write;
+                void *state;
+            } clean;
+        } log;
+        ....
+    };
+</verb>
+
+<sect4><tt/init()/
+
+	<P>
+<verb>
+        void
+        STINIT(SwapDir *);
+</verb>
+
+	<P>
+	The <tt/init/ function, of type <em/STINIT/ is called by
+	<tt/storeDirInit()/ when Squid first starts up.  The
+	<tt/init/ function should probably start the process of
+	reading saved state information from disk (aka the "rebuild"
+	procedure).
+
+<sect4><tt/newfs()/
+
+	<P>
+<verb>
+	void
+	STNEWFS(SwapDir *);
+</verb>
+
+	<P>
+	The <tt/newfs/ function, of type <em/STNEWFS/, is used to
+	prepare a cache_dir for use by squid.  It is called when
+	the user runs <em/squid -z/.  For the Unix file system,
+	the <tt/newfs/ function makes all the two-layer subdirectories.
+
+<sect4><tt/log.open()/
+
+	<P>
+<verb>
+	void
+	STLOGOPEN(SwapDir *);
+</verb>
+
+	<P>
+	The <tt/log.open/ function, of type <em/STLOGOPEN/,
+	is used to open or initialize the state-holding log
+	files (if any) for the storage system.  For UFS this
+	opens the <em/swap.state/ files.
+
+	<P>
+	The <tt/log.open/ function may be called any number of
+	times during Squid's execution.  For example, the
+	process of rotating, or writing clean logfiles closes
+	the state log and then re-opens them.  A <em/squid -k reconfigure/
+	does the same.
+
+<sect4><tt/log.close()/
+
+	<P>
+<verb>
+	void
+	STLOGCLOSE(SwapDir *);
+</verb>
+
+	<P>
+	The <tt/log.close/ function, of type <em/STLOGCLOSE/, is
+	obviously the counterpart to <tt/log.open/.  It must close
+	the open state-holding log files (if any) for the storage
+	system.
+
+<sect4><tt/log.write()/
+
+	<P>
+<verb>
+	void
+	STLOGWRITE(const SwapDir *, const StoreEntry *, int op);
+</verb>
+
+	<P>
+	The <tt/log.write/ function, of type <em/STLOGWRITE/, is
+	used to write an entry to the state-holding log file.  The
+	<em/op/ argument is either <em/SWAP_LOG_ADD/ or <em/SWAP_LOG_DEL/.
+	This feature may not be required by some storage systems
+	and can be implemented as a null-function (no-op).
+
+<sect4><tt/log.clean.open()/
+
+	<P>
+<verb>
+	int
+	STLOGCLEANOPEN(SwapDir *);
+</verb>
+
+	<P>
+	The <tt/log.clean.open/ function, of type <em/STLOGCLEANOPEN/,
+	is used for the process of writing "clean" state-holding
+	log files.  The clean-writing procedure is initiated by
+	the <em/squid -k rotate/ command.  This is a special case
+	because we want to optimize the process as much as possible.
+	This might be a no-op for some storage systems that don't
+	have the same logging issues as UFS.
+
+	<P>
+	The <em/log.clean.state/ pointer may be used to
+	keep state information for the clean-writing process, but
+	should not be accessed by upper layers.
+
+<sect4><tt/log.clean.write()/
+
+	<P>
+<verb>
+	void
+	STLOGCLEANWRITE(const StoreEntry *, SwapDir *);
+</verb>
+
+	<P>
+	The <tt/log.clean.write/ function, of type <em/STLOGCLEANWRITE/,
+	writes an entry to the clean log file (if any).
+
+	<P>
+	A NULL <em/StoreEntry/ argument indicates the end of
+	the clean-writing process and signals the storage
+	system to close the clean log, and rename or move them
+	to become the official state-holding log.
 
-<!-- %%%% Chapter : STORAGE MANAGER %%%% -->
-<sect>Storage Manager
 
 <!-- %%%% Chapter : FORWARDING SELECTION %%%% -->
 <sect>Forwarding Selection
@@ -799,73 +1137,81 @@
 
 <sect1> Introduction
 
-<P>
-The IP cache is a built-in component of squid providing
-Hostname to IP-Number translation functionality and managing 
-the involved data-structures. Efficiency concerns require
-mechanisms that allow non-blocking access to these mappings.
-The IP cache usually doesn't block on a request except for special 
-cases where this is desired (see below).
+	<P>
+	The IP cache is a built-in component of squid providing
+	Hostname to IP-Number translation functionality and managing
+	the involved data-structures. Efficiency concerns require
+	mechanisms that allow non-blocking access to these mappings.
+	The IP cache usually doesn't block on a request except for
+	special cases where this is desired (see below).
 
 <sect1> Data Structures 
 
-<P>
-The data structure used for storing name-address mappings
-is a small hashtable (<em>static hash_table *ip_table</em>),
-where structures of type <em>ipcache_entry</em> whose most
-interesting members are:
+	<P>
+	The data structure used for storing name-address mappings
+	is a small hashtable (<em>static hash_table *ip_table</em>),
+	where structures of type <em>ipcache_entry</em> whose most
+	interesting members are:
 
 <verb>
-struct _ipcache_entry {
-char *name;
-time_t lastref;
-ipcache_addrs addrs;
-struct _ip_pending *pending_head;
-char *error_message;
-unsigned char locks;
-ipcache_status_t status:3;
-}
+	struct _ipcache_entry {
+		char *name;
+		time_t lastref;
+		ipcache_addrs addrs;
+		struct _ip_pending *pending_head;
+		char *error_message;
+		unsigned char locks;
+		ipcache_status_t status:3;
+	}
 </verb>
 
 
 <sect1> External overview
 
-<P>
-Main functionality
-is provided through calls to:
-<descrip>
-<tag>ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerdata)
-</tag>
-where <em/name/ is the name of the host to resolve, <em/handler/ is a 
-pointer to the function to be called when the reply from the IP cache (or
-the DNS if the IP cache misses) and <em/handlerdata/ is information that
-is passed to the handler and does not affect the IP cache.
-<tag>ipcache_gethostbyname(const char *name,int flags)</tag>
-is different in that
-it only checks if an entry exists in it's data-structures and does not by
-default contact the DNS, unless this is requested, by setting the <em/flags/ to
-<em/IP_BLOCKING_LOOKUP/ or <em/IP_LOOKUP_IF_MISS/.
-<tag>ipcache_init()</tag> is called from <em/mainInitialize()/ after disk
-initialization and prior to the reverse fqdn cache initialization
-<tag>ipcache_restart()</tag> is called to clear the IP cache's data structures,
-cancel all pending requests. Currently, it is only called from
-<em/mainReconfigure/.
-</descrip>
+	<P>
+	Main functionality
+	is provided through calls to:
+	<descrip>
+
+	<tag>ipcache_nbgethostbyname(const char *name, IPH *handler,
+	void *handlerdata)</tag>
+	where <em/name/ is the name of the host to resolve,
+	<em/handler/ is a pointer to the function to be called when
+	the reply from the IP cache (or the DNS if the IP cache
+	misses) and <em/handlerdata/ is information that is passed
+	to the handler and does not affect the IP cache.
+
+	<tag>ipcache_gethostbyname(const char *name,int flags)</tag>
+	is different in that it only checks if an entry exists in
+	it's data-structures and does not by default contact the
+	DNS, unless this is requested, by setting the <em/flags/
+	to <em/IP_BLOCKING_LOOKUP/ or <em/IP_LOOKUP_IF_MISS/.
+
+	<tag>ipcache_init()</tag> is called from <em/mainInitialize()/
+	after disk initialization and prior to the reverse fqdn
+	cache initialization
+
+	<tag>ipcache_restart()</tag> is called to clear the IP
+	cache's data structures, cancel all pending requests.
+	Currently, it is only called from <em/mainReconfigure/.
+
+	</descrip>
 
 <sect1> Internal Operation 
 
-<P>
-Internally, the execution flow is as follows: On a miss, 
- <em/ipcache_getnbhostbyname/ checks whether a request for this name is already
-pending, and if positive, it creates a new entry using <em/ipcacheAddNew/ with
-the <em/IP_PENDING/ flag set . Then it calls <em/ipcacheAddPending/ to add a
-request to the queue together with data and handler.
-Else, <em/ipcache_dnsDispatch()/ is called to
-directly create a DNS query or to <em/ipcacheEnqueue()/ if all no DNS port is
-free.
-<em/ipcache_call_pending()/ is called regularly to walk down the pending
-list and call handlers. LRU clean-up is performed through <em/ipcache_purgelru()/
-according to the <em/ipcache_high/ threshold.
+	<P>
+	Internally, the execution flow is as follows: On a miss,
+	<em/ipcache_getnbhostbyname/ checks whether a request for
+	this name is already pending, and if positive, it creates
+	a new entry using <em/ipcacheAddNew/ with the <em/IP_PENDING/
+	flag set . Then it calls <em/ipcacheAddPending/ to add a
+	request to the queue together with data and handler.  Else,
+	<em/ipcache_dnsDispatch()/ is called to directly create a
+	DNS query or to <em/ipcacheEnqueue()/ if all no DNS port
+	is free.  <em/ipcache_call_pending()/ is called regularly
+	to walk down the pending list and call handlers. LRU clean-up
+	is performed through <em/ipcache_purgelru()/ according to
+	the <em/ipcache_high/ threshold.
 
 <!-- %%%% Chapter : SERVER PROTOCOLS %%%% -->
 <sect>Server Protocols
@@ -896,7 +1242,7 @@
 
 <sect>Callback Data Database
 
-<P>
+	<P>
 	Squid's extensive use of callback functions makes it very
 	susceptible to memory access errors.  For a blocking operation
 	with callback functions, the normal sequence of events is as
@@ -915,7 +1261,7 @@
 	to free the callback_data, or otherwise cancel the callback,
 	before the operation completes.
 
-<P>
+	<P>
 	The callback data database lets us do this in a uniform and
 	safe manner.  Every callback_data pointer must be added to the
 	database.  It is then locked while the blocking operation executes
@@ -935,7 +1281,7 @@
 	cbdataFree(callback_data);
 </verb>
 
-<P>
+	<P>
 	With this scheme, nothing bad happens if <tt/cbdataFree/ gets called
 	before <tt/cbdataUnlock/:
 <verb>
@@ -964,16 +1310,18 @@
 
 <!-- %%%% Chapter : HTTP Headers %%%% -->
 <sect>HTTP Headers
-<P>
-<em/Files:/
-	<tt/HttpHeader.c/,
-	<tt/HttpHeaderTools.c/,
-	<tt/HttpHdrCc.c/,
-	<tt/HttpHdrContRange.c/,
-	<tt/HttpHdrExtField.c/,
-	<tt/HttpHdrRange.c/
 
-<P> 
+	<P>
+	<em/Files:/
+        <tt/HttpHeader.c/,
+        <tt/HttpHeaderTools.c/,
+        <tt/HttpHdrCc.c/,
+        <tt/HttpHdrContRange.c/,
+        <tt/HttpHdrExtField.c/,
+        <tt/HttpHdrRange.c/
+
+
+	<P> 
 	<tt/HttpHeader/ class encapsulates methods and data for HTTP header
 	manipulation.  <tt/HttpHeader/ can be viewed as a collection of HTTP
 	header-fields with such common operations as add, delete, and find.
@@ -983,7 +1331,7 @@
 
 <sect1>General remarks
 
-<P>
+	<P>
 	<tt/HttpHeader/ is a collection (or array) of HTTP header-fields. A header
 	field is represented by an <tt/HttpHeaderEntry/ object. <tt/HttpHeaderEntry/ is
 	an (id, name, value) triplet.  Meaningful "Id"s are defined for
@@ -992,7 +1340,7 @@
 	<em/HDR_OTHER/.  Ids are formed by capitalizing the corresponding HTTP
 	header-field name and replacing dashes ('-') with underscores ('_').
 
-<P>
+	<P>
 	Most operations on <tt/HttpHeader/ require a "known" id as a parameter. The
 	rationale behind the later restriction is that Squid programmer should
 	operate on "known" fields only. If a new field is being added to
@@ -1000,7 +1348,7 @@
  
 <sect1>Life cycle
 
-<P> 
+	<P> 
 	<tt/HttpHeader/ follows a common pattern for object initialization and
 	cleaning:
 
@@ -1018,64 +1366,75 @@
     httpHeaderClean(&amp;hdr);
 </verb>
 
-<P> 
-	Prior to use, an <tt/HttpHeader/ must be initialized. A programmer must
-	specify if a header belongs to a request or reply message. The
-	"ownership" information is used mostly for statistical purposes.
-
-<P>
-	Once initialized, the <tt/HttpHeader/ object <em/must/ be, eventually,
-	cleaned.  Failure to do so will result in a memory leak.
-
-<P>
-	Note that there are no methods for "creating" or "destroying" a
-	"dynamic" <tt/HttpHeader/ object. Looks like headers are always stored as a
-	part of another object or as a temporary variable. Thus, dynamic
-	allocation of headers is not needed.
+	<P> 
+	Prior to use, an <tt/HttpHeader/ must be initialized. A
+	programmer must specify if a header belongs to a request
+	or reply message. The "ownership" information is used mostly
+	for statistical purposes.
+
+	<P>
+	Once initialized, the <tt/HttpHeader/ object <em/must/ be,
+	eventually, cleaned.  Failure to do so will result in a
+	memory leak.
+
+	<P>
+	Note that there are no methods for "creating" or "destroying"
+	a "dynamic" <tt/HttpHeader/ object. Looks like headers are
+	always stored as a part of another object or as a temporary
+	variable. Thus, dynamic allocation of headers is not needed.
 
 
 <sect1>Header Manipulation.
 
-<P>
-	The mostly common operations on HTTP headers are testing for a particular
-	header-field (<tt/httpHeaderHas()/), extracting field-values (<tt/httpHeaderGet*()/), and
-	adding new fields (<tt/httpHeaderPut*()/).
-
-<P>
-	<tt/httpHeaderHas(hdr, id)/ returns true if at least one header-field specified by
-	"id" is present in the header. Note that using <em/HDR_OTHER/ as an id is
-	prohibited.  There is usually no reason to know if there are "other"
+	<P>
+	The mostly common operations on HTTP headers are testing
+	for a particular header-field (<tt/httpHeaderHas()/),
+	extracting field-values (<tt/httpHeaderGet*()/), and adding
+	new fields (<tt/httpHeaderPut*()/).
+
+	<P>
+	<tt/httpHeaderHas(hdr, id)/ returns true if at least one
+	header-field specified by "id" is present in the header.
+	Note that using <em/HDR_OTHER/ as an id is prohibited.
+	There is usually no reason to know if there are "other"
 	header-fields in a header.
 
-<P>
-	<tt/httpHeaderGet&lt;Type&gt;(hdr, id)/ returns the value of the specified header-field.
-	The "Type" must match header-field type. If a header is not present a "null"
-	value is returned. "Null" values depend on field-type, of course.
-
-<P>
-	Special care must be taken when several header-fields with the same id are
-	preset in the header. If HTTP protocol allows only one copy of the specified
-	field per header (e.g. "Content-Length"), <tt/httpHeaderGet&lt;Type&gt;()/ will return
-	one of the field-values (chosen semi-randomly). If HTTP protocol allows for
-	several values (e.g. "Accept"), a "String List" will be returned.
-
-<P>
-	It is prohibited to ask for a List of values when only one value is permitted,
-	and visa-versa. This restriction prevents a programmer from processing one
-	value of an header-field while ignoring other valid values.
-
-<P>
-	<tt/httpHeaderPut&lt;Type&gt;(hdr, id, value)/ will add an header-field with a specified
-	field-name (based on "id") and field_value. The location of the newly added
-	field in the header array is undefined, but it is guaranteed to be after all
-	fields with the same "id" if any. Note that old header-fields with the same id
-	(if any) are not altered in any way.
-
-<P>
-	The value being put using one of the <tt/httpHeaderPut()/ methods is converted to
-	and stored as a String object.
+	<P>
+	<tt/httpHeaderGet&lt;Type&gt;(hdr, id)/ returns the value
+	of the specified header-field.  The "Type" must match
+	header-field type. If a header is not present a "null"
+	value is returned. "Null" values depend on field-type, of
+	course.
+
+	<P>
+	Special care must be taken when several header-fields with
+	the same id are preset in the header. If HTTP protocol
+	allows only one copy of the specified field per header
+	(e.g. "Content-Length"), <tt/httpHeaderGet&lt;Type&gt;()/
+	will return one of the field-values (chosen semi-randomly).
+	If HTTP protocol allows for several values (e.g. "Accept"),
+	a "String List" will be returned.
+
+	<P>
+	It is prohibited to ask for a List of values when only one
+	value is permitted, and visa-versa. This restriction prevents
+	a programmer from processing one value of an header-field
+	while ignoring other valid values.
+
+	<P>
+	<tt/httpHeaderPut&lt;Type&gt;(hdr, id, value)/ will add an
+	header-field with a specified field-name (based on "id")
+	and field_value. The location of the newly added field in
+	the header array is undefined, but it is guaranteed to be
+	after all fields with the same "id" if any. Note that old
+	header-fields with the same id (if any) are not altered in
+	any way.
+
+	<P>
+	The value being put using one of the <tt/httpHeaderPut()/
+	methods is converted to and stored as a String object.
 
-<P>
+	<P>
 	Example:
 
 <verb>
@@ -1085,21 +1444,21 @@
 		httpHeaderPutInt(hdr, HDR_AGE, age);
 </verb>
 
-<P>
-	There are two ways to delete a field from a header. To delete a "known" field
-	(a field with "id" other than <em/HDR_OTHER/), use <tt/httpHeaderDelById()/ function.
-	Sometimes, it is convenient to delete all fields with a given name ("known" or
-	not) using <tt/httpHeaderDelByName()/ method. Both methods will delete <em/all/ fields
-	specified.
-
-
-<P>
-
-	The <em/httpHeaderGetEntry(hdr, pos)/ function can be used for
-	iterating through all fields in a given header. Iteration is
-	controlled by the <em/pos/ parameter. Thus, several concurrent
-	iterations over one <em/hdr/ are possible. It is also safe to
-	delete/add fields from/to <em/hdr/ while iteration is in progress.
+	<P>
+	There are two ways to delete a field from a header. To
+	delete a "known" field (a field with "id" other than
+	<em/HDR_OTHER/), use <tt/httpHeaderDelById()/ function.
+	Sometimes, it is convenient to delete all fields with a
+	given name ("known" or not) using <tt/httpHeaderDelByName()/
+	method. Both methods will delete <em/all/ fields specified.
+
+	<P>
+	The <em/httpHeaderGetEntry(hdr, pos)/ function can be used
+	for iterating through all fields in a given header. Iteration
+	is controlled by the <em/pos/ parameter. Thus, several
+	concurrent iterations over one <em/hdr/ are possible. It
+	is also safe to delete/add fields from/to <em/hdr/ while
+	iteration is in progress.
 
 <verb>
 	/* delete all fields with a given name */
@@ -1111,79 +1470,268 @@
 	}
 </verb>
 
-	Note that <em/httpHeaderGetEntry()/ is a low level function and must
-	not be used if high level alternatives are available. For example, to
-	delete an entry with a given name, use the <em/httpHeaderDelByName()/
-	function rather than the loop above.
+	Note that <em/httpHeaderGetEntry()/ is a low level function
+	and must not be used if high level alternatives are available.
+	For example, to delete an entry with a given name, use the
+	<em/httpHeaderDelByName()/ function rather than the loop
+	above.
 
 <sect1>I/O and Headers.
 
-<P>
-	To store a header in a file or socket, pack it using <tt/httpHeaderPackInto()/
-	method and a corresponding "Packer". Note that <tt/httpHeaderPackInto/ will pack
-	only header-fields; request-lines and status-lines are not prepended, and
-	CRLF is not appended. Remember that neither of them is a part of HTTP
-	message header as defined by the HTTP protocol.
+	<P>
+	To store a header in a file or socket, pack it using
+	<tt/httpHeaderPackInto()/ method and a corresponding
+	"Packer". Note that <tt/httpHeaderPackInto/ will pack only
+	header-fields; request-lines and status-lines are not
+	prepended, and CRLF is not appended. Remember that neither
+	of them is a part of HTTP message header as defined by the
+	HTTP protocol.
 
 
 <sect1>Adding new header-field ids.
 
-<P> 
-	Adding new ids is simple. First add new HDR_ entry to the http_hdr_type
-	enumeration in enums.h. Then describe a new header-field attributes in
-	the HeadersAttrs array located in <tt/HttpHeader.c/. The last
-	attribute specifies field type. Five types are supported: integer
-	(<em/ftInt/), string (<em/ftStr/), date in RFC 1123 format
-	(<em/ftDate_1123/), cache control field (<em/ftPCc/), range field
-	(<em/ftPRange/), and content range field (<em/ftPContRange/).  Squid
-	uses type information to convert internal binary representation of
-	fields to their string representation (<tt/httpHeaderPut/ functions)
-	and visa-versa (<tt/httpHeaderGet/ functions).
+	<P> 
+	Adding new ids is simple. First add new HDR_ entry to the
+	http_hdr_type enumeration in enums.h. Then describe a new
+	header-field attributes in the HeadersAttrs array located
+	in <tt/HttpHeader.c/. The last attribute specifies field
+	type. Five types are supported: integer (<em/ftInt/), string
+	(<em/ftStr/), date in RFC 1123 format (<em/ftDate_1123/),
+	cache control field (<em/ftPCc/), range field (<em/ftPRange/),
+	and content range field (<em/ftPContRange/).  Squid uses
+	type information to convert internal binary representation
+	of fields to their string representation (<tt/httpHeaderPut/
+	functions) and visa-versa (<tt/httpHeaderGet/ functions).
 
-<P>
+	<P>
 	Finally, add new id to one of the following arrays:
-	<em/GeneralHeadersArr/, <em/EntityHeadersArr/, <em/ReplyHeadersArr/,
-	<em/RequestHeadersArr/.  Use HTTP specs to determine the applicable
-	array.  If your header-field is an "extension-header", its place is in
-	<em/ReplyHeadersArr/ and/or in <em/RequestHeadersArr/. You can also
-	use <em/EntityHeadersArr/ for "extension-header"s that can be used
-	both in replies and requests.  Header fields other than
-	"extension-header"s must go to one and only one of the arrays
-	mentioned above.
+	<em/GeneralHeadersArr/, <em/EntityHeadersArr/,
+	<em/ReplyHeadersArr/, <em/RequestHeadersArr/.  Use HTTP
+	specs to determine the applicable array.  If your header-field
+	is an "extension-header", its place is in <em/ReplyHeadersArr/
+	and/or in <em/RequestHeadersArr/. You can also use
+	<em/EntityHeadersArr/ for "extension-header"s that can be
+	used both in replies and requests.  Header fields other
+	than "extension-header"s must go to one and only one of
+	the arrays mentioned above.
 
-<P>
+	<P>
 	Also, if the new field is a "list" header, add it to the
-	<em/ListHeadersArr/ array.  A "list" field-header is the one that is
-	defined (or can be defined) using "#" BNF construct described in the
-	HTTP specs. Essentially, a field that may have more than one valid
-	field-value in a single header is a "list" field.
+	<em/ListHeadersArr/ array.  A "list" field-header is the
+	one that is defined (or can be defined) using "&num;" BNF
+	construct described in the HTTP specs. Essentially, a field
+	that may have more than one valid field-value in a single
+	header is a "list" field.
+
+	<P>
+	In most cases, if you forget to include a new field id in
+	one of the required arrays, you will get a run-time assertion.
+	For rarely used fields, however, it may take a long time
+	for an assertion to be triggered.
+
+	<P>
+	There is virtually no limit on the number of fields supported
+	by Squid. If current mask sizes cannot fit all the ids (you
+	will get an assertion if that happens), simply enlarge
+	HttpHeaderMask type in <tt/typedefs.h/.
 
-<P>
-	In most cases, if you forget to include a new field id in one of the required
-	arrays, you will get a run-time assertion. For rarely used fields, however, it
-	may take a long time for an assertion to be triggered.
 
-<P>
-	There is virtually no limit on the number of fields supported by Squid. If
-	current mask sizes cannot fit all the ids (you will get an assertion if that
-	happens), simply enlarge HttpHeaderMask type in <tt/typedefs.h/.
+<sect1>A Word on Efficiency.
 
+	<P>
+	<tt/httpHeaderHas()/ is a very cheap (fast) operation
+	implemented using a bit mask lookup.
 
-<sect1>A Word on Efficiency.
+	<P>
+	Adding new fields is somewhat expensive if they require
+	complex conversions to a string.
 
-<P>
-	<tt/httpHeaderHas()/ is a very cheap (fast) operation implemented using a bit mask
-	lookup.
+	<P>
+	Deleting existing fields requires scan of all the entries
+	and comparing their "id"s (faster) or "names" (slower) with
+	the one specified for deletion.
 
-<P>
-	Adding new fields is somewhat expensive if they require complex conversions to
-	a string.
+	<P>
+	Most of the operations are faster than their "ascii string"
+	equivalents.
+
+<sect>File Formats
+
+<sect1><em/swap.state/
 
 <P>
-	Deleting existing fields requires scan of all the entries and comparing their
-	"id"s (faster) or "names" (slower) with the one specified for deletion.
+NOTE: this information is current as of version 2.2.STABLE4.
 
 <P>
-	Most of the operations are faster than their "ascii string" equivalents.
+A <em/swap.state/ entry is defined by the <em/storeSwapLogData/
+structure, and has the following elements:
+<verb>
+struct _storeSwapLogData {
+    char op;
+    int swap_file_number;
+    time_t timestamp;
+    time_t lastref;
+    time_t expires;
+    time_t lastmod;
+    size_t swap_file_sz;
+    u_short refcount;
+    u_short flags;
+    unsigned char key[MD5_DIGEST_CHARS];
+};
+</verb>
+
+<descrip>
+<tag/op/
+	Either SWAP_LOG_ADD (1) when an object is added to
+	the disk storage, or SWAP_LOG_DEL (2) when an object is
+	deleted.
+
+<tag/swap_file_number/
+	The 32-bit file number which maps to a pathname.  Only
+	the low 24-bits are relevant.  The high 8-bits are
+	used as an index to an array of storage directories, and
+	are set at run time because the order of storage directories
+	may change over time.
+
+<tag/timestamp/
+	A 32-bit Unix time value that represents the time when
+	the origin server generated this response.  If the response
+	has a valid <em/Date:/ header, this timestamp corresponds
+	to that time.  Otherwise, it is set to the Squid process time
+	when the response is read (as soon as the end of headers are
+	found).
+
+<tag/lastref/
+	The last time that a client requested this object.
+	Strictly speaking, this time is set whenver the StoreEntry
+	is locked (via <em/storeLockObject()/). 
+
+<tag/expires/
+	The value of the response's <em/Expires:/ header, if any.
+	If the response does not have an <em/Expires:/ header, this
+	is set to -1.  If the response has an invalid (unparseable)
+	<em/Expires:/ header, it is also set to -1.  There are some cases
+	where Squid sets <em/expires/ to -2.  This happens for the
+	internal ``netdb'' object and for FTP URL responses.
+
+<tag/lastmod/
+	The value of the response's <em/Last-modified:/ header, if any.
+	This is set to -1 if there is no <em/Last-modified:/ header,
+	or if it is unparseable.
+
+<tag/swap_file_sz/
+	This is the number of bytes that the object occupies on
+	disk.  It includes the Squid ``swap file header''.
+
+<tag/refcount/
+	The number of times that this object has been accessed (referenced).
+	Since its a 16-bit quantity, it is susceptible to overflow
+	if a single object is accessed 65,536 times before being replaced.
+
+<tag/flags/
+	A copy of the <em/StoreEntry/ flags field.  Used as a sanity
+	check when rebuilding the cache at startup.  Objects that
+	have the KEY_PRIVATE flag set are not added back to the cache.
+
+<tag/key/
+	The 128-bit MD5 hash for this object.
+	
+</descrip>
+
+Note that <em/storeSwapLogData/ entries are written in native machine
+byte order.  They are not necessarily portable across architectures.
+
+<sect>Store ``swap meta'' Description
+<p>
+``swap meta'' refers to a section of meta data stored at the beginning
+of an object that is stored on disk.  This meta data includes information
+such as the object's cache key (MD5), URL, and part of the StoreEntry
+structure.
+
+<p>
+The meta data is stored using a TYPE-LENGTH-VALUE format.  That is,
+each chunk of meta information consists of a TYPE identifier, a
+LENGTH field, and then the VALUE (which is LENGTH octets long).
+
+<sect1>Types
+
+<p>
+As of Squid-2.3, the following TYPES are defined (from <em/enums.h/):
+<descrip>
+<tag/STORE_META_VOID/
+	Just a placeholder for the zeroth value.   It is never used
+	on disk.
+
+<tag/STORE_META_KEY_URL/
+	This represents the case when we use the URL as the cache
+	key, as Squid-1.1 does.  Currently we don't support using
+	a URL as a cache key, so this is not used.
+
+<tag/STORE_META_KEY_SHA/
+	For a brief time we considered supporting SHA (secure
+	hash algorithm) as a cache key.  Nobody liked it, and
+	this type is not currently used.
+
+<tag/STORE_META_KEY_MD5/
+	This represents the MD5 cache key that Squid currently uses.
+	When Squid opens a disk file for reading, it can check that
+	this MD5 matches the MD5 of the user's request.  If not, then
+	something went wrong and this is probably the wrong object.
+
+<tag/STORE_META_URL/
+	The object's URL.  This also may be matched against a user's
+	request for cache hits to make sure we got the right object.
+
+<tag/STORE_META_STD/
+	This is the ``standard metadata'' for an object.  Really
+	its just this middle chunk of the StoreEntry structure:
+<verb>
+	time_t timestamp;
+	time_t lastref;
+	time_t expires;
+	time_t lastmod;
+	size_t swap_file_sz;
+	u_short refcount;
+	u_short flags;
+</verb>
+
+<tag/STORE_META_HITMETERING/
+	Reserved for future hit-metering (RFC 2227) stuff.
+
+<tag/STORE_META_VALID/
+	?
+
+<tag/STORE_META_END/
+	Marks the last valid META type.
+
+</descrip>
+
+
+<sect1>Implementation Notes
+
+<p>
+When writing an object to disk, we must first write the meta data.
+This is done with a couple of functions.  First, <tt/storeSwapMetaPack()/
+takes a <em/StoreEntry/ as a parameter and returns a <em/tlv/ linked
+list.  Second, <tt/storeSwapMetaPack()/ converts the <em/tlv/ list
+into a character buffer that we can write.
+
+<p>
+Note that the <em/MemObject/ has a member called <em/swap_hdr_sz/.
+This value is the size of that character buffer; the size of the
+swap file meta data.  The <em/StoreEntry/ has a member named
+<em/swap_file_sz/ that represents the size of the disk file.
+Thus, the size of the object ``content'' is
+<verb>
+	StoreEntry->swap_file_sz  - MemObject->swap_hdr_sz;
+</verb>
+Note that the swap file content includes the HTTP reply headers
+and the HTTP reply body (if any).
+
+<p>
+When reading a swap file, there is a similar process to extract
+the swap meta data.  First, <tt/storeSwapMetaUnpack()/ converts a
+character buffer into a <em/tlv/ linked list.  It also tells us
+the value for <em/MemObject->swap_hdr_sz/.
 
 </article>
Index: squid/errors/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Attic/Makefile.in,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Makefile.in	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+# $Id: Makefile.in,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
 #
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
@@ -45,6 +45,25 @@
 		mkdir $(DEFAULT_ERROR_DIR); \
 	fi
 
+# undocumented hack.  You can use this target to create multi-lingual
+# error pages.  For example:
+#
+#	make ADDLANG=English addlang
+#
+# by Andres Kroonmaa <andre@mail.lbi.ee>
+#
+addlang: all
+	-@if test -d $(srcdir)/$(ADDLANG); then \
+	cd $(srcdir)/$(ADDLANG)/ ; \
+	for f in ERR_*; do \
+		if test -f $(DEFAULT_ERROR_DIR)/$$f ; then \
+			echo "appending $(ADDLANG)/$$f"; \
+			echo "<HR>" >> $(DEFAULT_ERROR_DIR)/$$f ; \
+			cat $$f >> $(DEFAULT_ERROR_DIR)/$$f; \
+		fi; \
+	done; \
+	fi
+
 clean:
 
 distclean: clean
Index: squid/errors/Bulgarian/ERR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí</TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_CACHE_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_CACHE_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_CACHE_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_CACHE_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Äîñòúï äî êåøà îòêàçàí</TITLE>
 </HEAD>
 <BODY>
Index: squid/errors/Bulgarian/ERR_CACHE_MGR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_CACHE_MGR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_CACHE_MGR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_CACHE_MGR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Îòêàçàí äîñòúï äî êåø ìåíèäæúðà</TITLE>
 </HEAD>
 <BODY>
Index: squid/errors/Bulgarian/ERR_CANNOT_FORWARD
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_CANNOT_FORWARD,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_CANNOT_FORWARD	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_CANNOT_FORWARD	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_CONNECT_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_CONNECT_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_CONNECT_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_CONNECT_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_DNS_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_DNS_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_DNS_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_DNS_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_FORWARDING_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FORWARDING_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FORWARDING_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FORWARDING_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_FTP_DISABLED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_DISABLED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_DISABLED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_DISABLED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_FTP_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
+<TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ÃÐÅØÊÀ</H1>
+<H2> Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Âúçíèêíà ãðåøêà ïðè àóòîðèçàöèÿ ñ îòäàëå÷åíèÿ FTP ñúðâúð ïðè äîñòàâêàòà íà URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Êåø ñúðâúðà èçïðàòè ñëåäíàòà FTP êîìàíäà:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+è ïîëó÷è òîçè îòãîâîð
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Bulgarian/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,25 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
+<TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ÃÐÅØÊÀ</H1>
+<H2> Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+Òîçè îáåêò íå ìîæå äà áúäå äîñòàâåí:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Êåø ñúðâúðà èçïðàòè ñëåäíàòà FTP êîìàíäà:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+è ïîëó÷è òîçè îòãîâîð
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+<PRE>
+   Òîâà áè ìîãëî äà áúäå ïðè÷èíåíî îò çàÿâêà, â êîÿòî å ïîñî÷åí
+   àáñîëþòåí ïúò (êîåòî å íåïðàâèëíî ñïîðåä äîêóìåíò RFC 1738).
+   Àêî òîâà å ïðè÷èíàòà, òî ôàéëúò áè ìîãúë äà áúäå íàìåðåí íà
+   àäðåñ <A HREF="%B">%B</A>.
+</PRE>
 </P>
 
Index: squid/errors/Bulgarian/ERR_FTP_PUT_CREATED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_PUT_CREATED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_PUT_CREATED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_PUT_CREATED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>FTP PUT çàÿâêà óñïåøíà: Ôàéëúò ñúçäàäåí</TITLE>
 </HEAD><BODY>
 <H1>Ïðîöåäóðàòà óñïåøíà</H1>
Index: squid/errors/Bulgarian/ERR_FTP_PUT_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_PUT_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_PUT_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_PUT_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: íåóñïåøíà FTP çàÿâêà </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_FTP_PUT_MODIFIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_PUT_MODIFIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_PUT_MODIFIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_PUT_MODIFIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>Óñïåøíà FTP PUT çàÿâêà: Ôàéëúò îáíîâåí</TITLE>
 </HEAD><BODY>
 <H1>Ïðîöåäóðàòà óñïåøíà</H1>
Index: squid/errors/Bulgarian/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
+<TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ÃÐÅØÊÀ</H1>
+<H2> Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+FTP ñúðâúðòúò å íåäîñòúïåí â ìîìåíòà
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Êåø ñúðâúðà èçïðàòè ñëåäíàòà FTP êîìàíäà:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+è ïîëó÷è òîçè îòãîâîð
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Bulgarian/ERR_INVALID_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_INVALID_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_INVALID_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_INVALID_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_INVALID_URL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_INVALID_URL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_INVALID_URL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_INVALID_URL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_LIFETIME_EXP
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_LIFETIME_EXP,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_LIFETIME_EXP	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_LIFETIME_EXP	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_NO_RELAY
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_NO_RELAY,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_NO_RELAY	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_NO_RELAY	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_ONLY_IF_CACHED_MISS
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_ONLY_IF_CACHED_MISS,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_READ_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_READ_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_READ_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_READ_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_READ_TIMEOUT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_READ_TIMEOUT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_READ_TIMEOUT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_READ_TIMEOUT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
+<TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ÃÐÅØÊÀ</H1>
+<H2> Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </H2>
 <HR>
 <P>
-While trying to retrieve the URL:
+Ïðè îïèò çà äîñòàâêà íà URL-a:
 <A HREF="%U">%U</A>
 <P>
-The following error was encountered:
+Âúçíèêíà ñëåäíàòà ãðåøêà:
 <UL>
 <P>
-This cache is in the process of shutting down and can not
-service your request at this time.  Please retry your
-request again soon.
+Êåø ñúðâúðúò å â ïðîöåñ íà ðåñòàðòèðàíå è â ìîìåíòà íå ìîæå äà èçïúëíè âàøàòà çàÿâêà. 
+Ìîëÿ îïèòàéòå îòíîâî ñëåä íÿêîëêî ìèíóòè.
 </P>
Index: squid/errors/Bulgarian/ERR_SOCKET_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_SOCKET_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_SOCKET_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_SOCKET_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_UNSUP_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_UNSUP_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_UNSUP_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_UNSUP_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_URN_RESOLVE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_URN_RESOLVE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_URN_RESOLVE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_URN_RESOLVE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_WRITE_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_WRITE_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_WRITE_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_WRITE_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/ERR_ZERO_SIZE_OBJECT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/ERR_ZERO_SIZE_OBJECT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE> ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí </TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Bulgarian/README
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/README,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/README	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/README	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,2 +1,3 @@
-Thank you to Evgeny Gechev <etg@setcom.bg> for
+Thank you to Evgeny Gechev <etg@setcom.bg> and 
+Svetlin Simeonov <simeonov@netplusdb.bg> for
 creating these error pages in Bulgarian!
Index: squid/errors/Bulgarian/generic
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Bulgarian/generic,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Bulgarian/generic	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Bulgarian/generic	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,4 +1,5 @@
 <HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 <TITLE>ÃÐÅØÊÀ: Çàÿâåíèÿò îáåêò íå ìîæå äà áúäå äîñòàâåí</TITLE>
 </HEAD><BODY>
 <H1>ÃÐÅØÊÀ</H1>
Index: squid/errors/Czech/ERR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -15,10 +15,11 @@
 <STRONG>
 Access Denied.
 </STRONG>
-<P>
-Pøistup k dokumentu byl stornován v dùsledku nedostatèných pøístupových
-práv. Pokud jste pøesvìdèeni, ¾e se jedná o chybu, kontaktujte správce
-vzdáleného serveru.
 </UL>
 </P>
 
+<P>
+Pøístup k dokumentu byl stornován v dùsledku nedostateèných pøístupových
+práv. Pokud jste pøesvìdèeni, ¾e se jedná o chybu, kontaktujte
+<A HREF="mailto:%w">správce</a> vzdáleného serveru.
+</P>
Index: squid/errors/Czech/ERR_CACHE_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_CACHE_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_CACHE_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_CACHE_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 <HTML><HEAD>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
-<TITLE>CHYBA: Pristup ke cache serveru odmitnut</TITLE>
+<TITLE>CHYBA: Pristup ke cache serveru zamítnut</TITLE>
 </HEAD>
 <BODY>
 <H1>CHYBA</H1>
@@ -19,7 +19,7 @@
 </UL>
 </P>
 
-<P>Olouváme se, ale  pøístup k:
+<P>Omlouváme se, ale pøístup k:
 <PRE>    %U</PRE>
 je povolen a¾ po autorizaci.
 </P>
@@ -28,7 +28,7 @@
 
 Pro úspì¹nou autorizaci potøebujete prohlí¾eèe NETSCAPE 2.0 a vy¹¹í,
 Microsoft Internet Explorer 3.0 nebo prohlí¾eè podporující protokol
-HTTP/1.1. V pøípadì problému se prosím obra»te na<A HREF="mailto:%w">cache
+HTTP/1.1. V pøípadì problému se prosím obra»te na <A HREF="mailto:%w">cache
 administratora</a> nebo si zmìòte  
-<A HREF="http://%h/cgi-bin/chpasswd.cgi\">heslo</a>.
+<A HREF="http://%h/cgi-bin/chpasswd.cgi">heslo</a>.
 </P>
Index: squid/errors/Czech/ERR_CACHE_MGR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_CACHE_MGR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_CACHE_MGR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_CACHE_MGR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,10 +1,10 @@
 <HTML><HEAD>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
-<TITLE>CHYBA: Cache Manager Access Denied</TITLE>
+<TITLE>CHYBA: Pristup ke cache manazeru zamitnut</TITLE>
 </HEAD>
 <BODY>
 <H1>CHYBA</H1>
-<H2>Cache Manager Access Denied</H2>
+<H2>Pøístup ke cache mana¾eru zamítnut</H2>
 <HR>
 <P>
 Pøi pokusu o pøístup k:
@@ -27,7 +27,7 @@
 <P> 
 Pro úspì¹nou autorizaci potøebujete prohlí¾eèe NETSCAPE 2.0 a vy¹¹í,
 Microsoft Internet Explorer 3.0 nebo prohlí¾eè podporující protokol
-HTTP/1.1. V pøípadì problému se prosím obra»te na<A HREF="mailto:%w">cache
+HTTP/1.1. V pøípadì problému se prosím obra»te na <A HREF="mailto:%w">cache
 administratora</a> nebo si zmìòte
-<A HREF="http://%h/cgi-bin/chpasswd.cgi\">heslo</a>.
-</p?
\ No newline at end of file
+<A HREF="http://%h/cgi-bin/chpasswd.cgi">heslo</a>.
+</P>
\ No newline at end of file
Index: squid/errors/Czech/ERR_CANNOT_FORWARD
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_CANNOT_FORWARD,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_CANNOT_FORWARD	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_CANNOT_FORWARD	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Po¾adavek není mo¾no pøemìrovat.
+Unable to forward this request at this time.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_CONNECT_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_CONNECT_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_CONNECT_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_CONNECT_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Connection Failed
+Connection Failed.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_DNS_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_DNS_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_DNS_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_DNS_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -10,7 +10,7 @@
 <P>
 se objevila následující chyba:
 <BLOCKQUOTE>
-Jméno serveru není mo¾no pøevést na IP adresu
+Jméno serveru není mo¾no pøevést na IP adresu.
 <I>%H</I>
 </BLOCKQUOTE>
 </UL>
@@ -23,9 +23,11 @@
 
 <P>
 To znamená ¾e:
-<PRE>
+<P>
+<UL>
+<LI>
 Cache server nebyl schopen získat adresu serveru uvedeného v URL.
 Zkontrolujte prosím adresu.
-</PRE>
+</UL>
 </P>
 
Index: squid/errors/Czech/ERR_FORWARDING_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FORWARDING_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FORWARDING_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FORWARDING_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -18,7 +18,7 @@
 </UL>
 
 <P>
-Cache server nepøesmìruje Vá¹ po¾adavek, proto¾e by to nedovolují vztahy v
-hierarchické struktuøe cache serverù. %i je pravd¾podobnì chybnì
+Cache server nepøesmìruje Vá¹ po¾adavek, proto¾e to nedovolují vztahy v
+hierarchické struktuøe cache serverù. %i je pravdìpodobnì chybnì
 nakonfigurovaný cache server.
 </P>
Index: squid/errors/Czech/ERR_FTP_DISABLED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_DISABLED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_DISABLED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_DISABLED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,6 +1,5 @@
 <HTML><HEAD>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
-<A HREF="http://%h/cgi-bin/chpasswd.cgi\">heslo</a>.
 <TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
 <H1>CHYBA</H1>
@@ -14,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-FTP is Disabled
+FTP is Disabled.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_FTP_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -10,7 +10,7 @@
 <A HREF="%U">%U</A>
 se objevila chyba FTP.
 <P>
-Squid odeslal následující  FTP pøíkaz:
+Squid odeslal následující FTP pøíkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
 a obdr¾el tuto odpovìï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
Index: squid/errors/Czech/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,18 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Pøi pokusu o pøístup k URL:
 <A HREF="%U">%U</A>
+se objevila chyba autorizace FTP.
 <P>
-Squid sent the following FTP command:
+Squid odeslal následující FTP pøíkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾el tuto odpovìï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Czech/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,22 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+Po¾adovaný dokument na adrese:
 <A HREF="%U">%U</A>
+nebyl nalezen.
 <P>
-Squid sent the following FTP command:
+Squid odeslal následující FTP pøíkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾el tuto odpovìï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+To mù¾e být zapøíèinìno pou¾itím absolutní cesty v FTP URL (co¾ odporuje RFC
+1738). V tomto pøípadì mù¾e být dokument nalezen na <A HREF="%B">%B</A>.
 </P>
 
Index: squid/errors/Czech/ERR_FTP_PUT_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_PUT_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_PUT_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_PUT_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,8 +1,16 @@
-<HTML><HEAD> <meta http-equiv="Content-Type" content="text/html;
-charset=iso-8859-2"> <TITLE>CHYBA: neuspesny FTP upload </TITLE>
-</HEAD><BODY> <H1>CHYBA</H1> <H2>FTP PUT/upload neúspì¹ný</H2> <HR> <P> Pøi
-pokusu o PUT následujícího URL: <A HREF="%U">%U</A> <P> odeslal Squid
-následující FTP pøíkaz: <PRE><STRONG>
+<HTML><HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: neuspesny FTP upload </TITLE>
+</HEAD><BODY>
+<H1>CHYBA</H1>
+<H2>FTP PUT/upload neúspì¹ný</H2>
+<HR>
+<P>
+Pøi pokusu o PUT následujícího URL:
+<A HREF="%U">%U</A>
+<P>
+odeslal Squid následující FTP pøíkaz:
+<PRE><STRONG>
         %f
 </STRONG></PRE>
 a obdr¾el tuto odpovìï
@@ -11,8 +19,10 @@
 </STRONG></PRE>
 <P>
 Zkuste:
-<PRE>
+<P>
+<UL>
+<LI>
 zkontrolovat cestu, pøístupová práva, volné místo na disku a zkuste to znova.
-</PRE>
+</UL>
 </P>
 
Index: squid/errors/Czech/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2"> 
+<TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+FTP server je pøetí¾en a nemù¾e poslat nasledující dokument:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid odeslal následující FTP pøíkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾el tuto odpovìï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Czech/ERR_INVALID_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_INVALID_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_INVALID_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_INVALID_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -6,7 +6,6 @@
 <H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-While trying to process the request:
 Pøi provádìní po¾adavku:
 <PRE>
 %R
@@ -16,18 +15,18 @@
 <UL>
 <LI>
 <STRONG>
-Invalid Request
+Invalid Request.
 </STRONG>
 </UL>
 
 <P>
-Èáast HTTP po¾adavku je chybná:
+Èást HTTP po¾adavku je chybná:
 <UL>
 <LI>Chybná nebo chybìjící HTTP metoda (POST, GET)
 <LI>Chybìjící URL
 <LI>Chybìjící identifikátor HTTP (HTTP/1.0)
 <LI>Po¾adavek mù¾e být pøíli¹ velký
 <LI>Chybìjící polo¾ka Content-Lenght pro po¾adavky POST a GET
-<LI>Zakázaný znak v hostnam; (podtr¾ítko ??)
+<LI>Chybný znak v hostname (podtr¾ítko ??)
 </UL>
 </P>
Index: squid/errors/Czech/ERR_INVALID_URL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_INVALID_URL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_INVALID_URL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_INVALID_URL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Invalid URL
+Invalid URL.
 </STRONG>
 </UL>
 
@@ -23,6 +23,6 @@
 <LI>Chybný nebo chybìjící protokol (http:// ..)
 <LI>Chybìjící hostname
 <LI>Chybný double-escape v URL cestì
-<LI>Chybný znak v hostname (podtr¾ítko _)
+<LI>Chybný znak v hostname (podtr¾ítko ??)
 </UL>
 </P>
Index: squid/errors/Czech/ERR_LIFETIME_EXP
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_LIFETIME_EXP,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_LIFETIME_EXP	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_LIFETIME_EXP	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,11 +13,10 @@
 <UL>
 <LI>
 <STRONG>
-Connection Lifetime Expired
+Connection Lifetime Expired.
 </STRONG>
 </UL>
 
 <P>
-Squid stornoval po¾adavek z dùvodu pøekoroèní maximální délky trvání
-spojení. 
+Squid stornoval po¾adavek z dùvodu pøekroèení maximální délky trvání spojení. 
 </P>
Index: squid/errors/Czech/ERR_NO_RELAY
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_NO_RELAY,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_NO_RELAY	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_NO_RELAY	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,10 +13,10 @@
 <UL>
 <LI>
 <STRONG>
-No Wais Relay
+No Wais Relay.
 </STRONG>
 </UL>
 
 <P>
-Cache server nema definovaný WAIS Relay! Vyhubujte administratorovi.
-</p>
\ No newline at end of file
+Cache server nemá definovaný WAIS Relay! Vyhubujte <A HREF="mailto:%w">administratorovi</A>.
+</P>
\ No newline at end of file
Index: squid/errors/Czech/ERR_ONLY_IF_CACHED_MISS
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_ONLY_IF_CACHED_MISS,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,15 +13,9 @@
 <UL>
 <LI>
 <STRONG>
-Po¾adovaný dokument se nenachází  v cachi pøièm¾ byla specifikována direktiva
-<code>only-if-cached</code>.
+Po¾adovaný dokument se nenachází v cachi, pøièem¾ byla specifikována direktiva
+<code><u>only-if-cached</u></code>.
 </STRONG>
 </UL>
 
-<P>
-
-You have issued a request with a <code>only-if-cached</code> cache control
-directive. The document was not found in the cache, <em>or</em> it required
-revalidation prohibited by <code>only-if-cached</code> directive.
-
 </P>
Index: squid/errors/Czech/ERR_READ_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_READ_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_READ_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_READ_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Read Error
+Read Error.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_READ_TIMEOUT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_READ_TIMEOUT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_READ_TIMEOUT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_READ_TIMEOUT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Read Timeout
+Read Timeout.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -3,15 +3,19 @@
 <TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
 <H1>CHYBA</H1>
-<H2>Poøadovaný dokument je nedostupný</H2>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
 Pøi pokusu o pøístup k:
 <A HREF="%U">%U</A>
 <P>
 se objevila následující chyba:
-<UL>
 <P>
+<UL>
+<LI>
+<STRONG>
 Tento cache server je právì restartován a nemù¾e obslou¾it Vá¹ po¾adavek.
 Zkuste to za chvíli znova.
+</STRONG>
+</UL>
 </P>
Index: squid/errors/Czech/ERR_SOCKET_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_SOCKET_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_SOCKET_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_SOCKET_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Socket Failure
+Socket Failure.
 </STRONG>
 </UL>
 
Index: squid/errors/Czech/ERR_UNSUP_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_UNSUP_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_UNSUP_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_UNSUP_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,12 +13,12 @@
 <UL>
 <LI>
 <STRONG>
-Unsupported Request Method and Protocol
+Unsupported Request Method and Protocol.
 </STRONG>
 </UL>
 
 <P>
 Squid nepodporuje v¹echny typy metod u v¹ech protokolù. Napø. není mo¾no
-pou¾it metodu POST u slu¾by GOPHER
+pou¾it metodu POST u slu¾by GOPHER.
 </P>
 
Index: squid/errors/Czech/ERR_URN_RESOLVE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_URN_RESOLVE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_URN_RESOLVE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_URN_RESOLVE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,22 +1,22 @@
 <HTML><HEAD>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2"> 
-<TITLE>CHYBA: Po¾adované  URN je nedostupné</TITLE>
+<TITLE>CHYBA: Po¾adované URN je nedostupné</TITLE>
 </HEAD><BODY>
 <H1>CHYBA</H1>
-<H2>A URL pro po¾adované  URN je nedostupné</H2>
+<H2>URL pro po¾adované URN je nedostupné</H2>
 <HR>
 <P>
-Pøi pokusu o pøístup k  URN:
+Pøi pokusu o pøístup k URN:
 <A HREF="%U">%U</A>
 <P>
 se objevila následující chyba:
 <UL>
 <LI>
 <STRONG>
-Cannot Resolve URN
+Cannot Resolve URN.
 </STRONG>
 </UL>
 
 <P>
-Hey, don't expect too much from URNs on %T :)
+Hey, neoèekáváte pøíli¹ mnoho od URN na %T :)
 </P>
Index: squid/errors/Czech/ERR_WRITE_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_WRITE_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_WRITE_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_WRITE_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,7 +13,7 @@
 <UL>
 <LI>
 <STRONG>
-Write Error
+Write Error.
 </STRONG>
 </UL>
 
@@ -22,5 +22,5 @@
 <PRE><I>    %E</I></PRE>
 
 <P>
-Chyba zápisu na sí». Opakjte prosím po¾adavek.
+Chyba zápisu na sí». Opakujte prosím po¾adavek.
 </P>
Index: squid/errors/Czech/ERR_ZERO_SIZE_OBJECT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/ERR_ZERO_SIZE_OBJECT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,10 +13,10 @@
 <UL>
 <LI>
 <STRONG>
-Zero Sized Reply
+Zero Sized Reply.
 </STRONG>
 </UL>
 
 <P>
-Squid neobdr¾el v opdovìdi na tento dotaz ¾ádná data.
+Squid neobdr¾el v odpovìdi na tento dotaz ¾ádná data.
 </P>
Index: squid/errors/Czech/README
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Czech/README,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Czech/README	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Czech/README	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,2 +1,2 @@
-Thank you to Jakub Nantl <Jakub.Nantl@opf.slu.cz> for
-creating these error pages in Czech!
+Thank you to Jakub Nantl <Jakub.Nantl@angel.cz> and Radek Malcic
+<malcic@sdc.bno.cdrail.cz> for creating these error pages in Czech!
Index: squid/errors/English/ERR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -19,5 +19,5 @@
 being allowed at this time.  Please contact your service provider if
 you feel this is incorrect.
 </UL>
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
 
Index: squid/errors/English/ERR_CANNOT_FORWARD
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_CANNOT_FORWARD,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_CANNOT_FORWARD	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_CANNOT_FORWARD	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -24,4 +24,4 @@
     direct connections to origin servers, and
 <LI>All configured parent caches are currently unreachable.
 </UL>
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_CONNECT_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_CONNECT_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_CONNECT_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_CONNECT_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -22,4 +22,4 @@
 
 <P>
 The remote host or network may be down.  Please try the request again.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_DNS_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_DNS_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_DNS_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_DNS_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -26,5 +26,4 @@
  The cache was not able to resolve the hostname presented in the URL. 
  Check if the address is correct. 
 </PRE>
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FORWARDING_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FORWARDING_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FORWARDING_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_FORWARDING_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -20,4 +20,4 @@
 This cache will not forward your request because it is trying to enforce a
 sibling relationship.  Perhaps the client at %i is a cache which has been
 misconfigured.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_DISABLED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_DISABLED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FTP_DISABLED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_FTP_DISABLED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -18,4 +18,4 @@
 
 <P>
 This cache does not support FTP.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_FAILURE,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/errors/English/ERR_FTP_FAILURE	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/errors/English/ERR_FTP_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -14,5 +14,4 @@
 and then received this reply
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/English/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -14,5 +14,4 @@
 and then received this reply
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/English/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,5 +17,4 @@
 This might be caused by an FTP URL with an absolute path (which does
 not comply with RFC 1738).  If this is the cause, then the file
 can be found at <A HREF="%B">%B</A>.
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_PUT_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_PUT_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FTP_PUT_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_FTP_PUT_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -21,5 +21,4 @@
 <PRE>
 Check path, permissions, diskspace and try again.
 </PRE>
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/English/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -13,5 +13,4 @@
 and then received this reply
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_INVALID_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_INVALID_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_INVALID_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_INVALID_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -28,4 +28,4 @@
 <LI>Content-Length missing for POST or PUT requests
 <LI>Illegal character in hostname; underscores are not allowed
 </UL>
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_INVALID_URL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_INVALID_URL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_INVALID_URL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_INVALID_URL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -24,4 +24,4 @@
 <LI>Illegal double-escape in the URL-Path
 <LI>Illegal character in hostname; underscores are not allowed
 </UL>
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_LIFETIME_EXP
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_LIFETIME_EXP,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_LIFETIME_EXP	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_LIFETIME_EXP	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -19,4 +19,4 @@
 <P>
 Squid has terminated the request because it has exceeded the maximum
 connection lifetime.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_NO_RELAY
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_NO_RELAY,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_NO_RELAY	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_NO_RELAY	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -18,4 +18,4 @@
 
 <P>
 There is no WAIS Relay host defined for this Cache!  Yell at the administrator.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_ONLY_IF_CACHED_MISS
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_ONLY_IF_CACHED_MISS,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_ONLY_IF_CACHED_MISS	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -23,4 +23,4 @@
 directive. The document was not found in the cache, <em>or</em> it required
 revalidation prohibited by <code>only-if-cached</code> directive.
 
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_READ_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_READ_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_READ_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_READ_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -23,4 +23,4 @@
 <P>
 An error condition occurred while reading data from the network.  Please
 retry your request.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_READ_TIMEOUT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_READ_TIMEOUT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_READ_TIMEOUT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_READ_TIMEOUT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -23,4 +23,4 @@
 <P>
 A Timeout occurred while waiting to read data from the network.  The network
 or server may be down or congested.  Please retry your request.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/English/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -14,4 +14,4 @@
 This cache is in the process of shutting down and can not
 service your request at this time.  Please retry your
 request again soon.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_SOCKET_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_SOCKET_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_SOCKET_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_SOCKET_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -23,4 +23,4 @@
 <P>
 Squid is unable to create a TCP socket, presumably due to excessive load.
 Please retry your request.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_UNSUP_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_UNSUP_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_UNSUP_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_UNSUP_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -19,5 +19,4 @@
 <P>
 Squid does not support all request methods for all access protocols.
 For example, you can not POST a Gopher request.
-</P>
-
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_URN_RESOLVE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_URN_RESOLVE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_URN_RESOLVE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_URN_RESOLVE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -18,4 +18,4 @@
 
 <P>
 Hey, don't expect too much from URNs on %T :)
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_WRITE_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_WRITE_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_WRITE_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_WRITE_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -23,4 +23,4 @@
 <P>
 An error condition occurred while writing to the network.  Please retry your
 request.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/English/ERR_ZERO_SIZE_OBJECT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/English/ERR_ZERO_SIZE_OBJECT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/English/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/English/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -18,4 +18,4 @@
 
 <P>
 Squid did not receive any data for this request.
-</P>
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
Index: squid/errors/French/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/French/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/French/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/French/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERREUR: L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ERREUR</H1>
+<H2>L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Une erreur d'authentification sur un FTP a eu lieu.
+En tentant de charger l'URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid a envoy&eacute; la commande FTP suivante:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+et a recu en r&eacute;ponse
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/French/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/French/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/French/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/French/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,22 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERREUR: L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ERREUR</H1>
+<H2>L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+L'URL suivante n'a pu &ecirc;tre charg&eacute;e:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid a envoy&eacute; la commande FTP suivante:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+et a recu en retour:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+Ceci pourrait etre caus&eacute; par une URL de FTP avec un
+chemin absolu (ce qui n'est pas conforme au RFC 1738) . Si c'est
+effectivement le cas, alors le fichier se trouve &agrave;
+l'adresse <A HREF="%B">%B</A>.
 </P>
 
Index: squid/errors/French/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/French/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/French/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/French/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,16 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERREUR: L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ERREUR</H1>
+<H2>L'URL demand&eacute;e n'a pu &ecirc;tre charg&eacute;e.</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+Le serveur FTP &eacute;tait trop encombr&eacute; pour charger l'URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid a envoy&eacute; la commande FTP suivante:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+et a recu la r&eacute;ponse suivante en retour:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/French/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/French/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/French/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/French/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERREUR: La requete demand&eacute;e n'a pu etre effectu&eacute;e</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>ERREUR</H1>
+<H2>La requete demand&eacute;e n'a pu etre effectu&eacute;e</H2>
 <HR>
 <P>
-While trying to retrieve the URL:
+En essayant de charger l'URL:
 <A HREF="%U">%U</A>
 <P>
-The following error was encountered:
+L'erreur suivante fut rencontr&eacute;e:
 <UL>
 <P>
-This cache is in the process of shutting down and can not
-service your request at this time.  Please retry your
-request again soon.
+Ce cache est en cours de mise hors-service temporaire et il
+lui est impossible de satisfaire votre requete actuellement.
+Veuillez r&eacute;iterer votre requete ult&eacute;rieurement.
 </P>
Index: squid/errors/French/README
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/French/README,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/French/README	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/French/README	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,2 +1,2 @@
-Thank you to Frank DENIS -Jedi/Sector One- <j@stdc.org> for
+Thank you to Frank DENIS -Jedi/Sector One- <j@4u.net> for
 creating these error pages in French!
Index: squid/errors/Hungarian/ERR_FTP_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Hungarian/ERR_FTP_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Hungarian/ERR_FTP_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Hungarian/ERR_FTP_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -15,7 +15,7 @@
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
 A hibát lehet hogy az okozta, hogy az FTP URL abszolút elérési utat tartalmaz
-(ami nem felel meg az RFC 1738 elõírásnak). Amennyiben az a hiba oka, akkor a
+(ami nem felel meg az RFC 1738 elõírásnak). Amennyiben ez a hiba oka, akkor
 az állományt a <A HREF="%B">%B</A> címen lehet megtalálni.
 </P>
 
Index: squid/errors/Hungarian/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Hungarian/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Hungarian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Hungarian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,18 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>HIBA: A kért URL nem tölthetõ le</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>HIBA</H1>
+<H2>A kért URL nem tölthetõ le</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+FTP autentikációs hiba történt
+az alábbi URL letöltésekor:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+A Squid az alábbi FTP parancsot küldte:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+és ezt a választ kapta
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Hungarian/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Hungarian/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Hungarian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Hungarian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,22 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>HIBA: A kért URL nem tölthetõ le</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>HIBA</H1>
+<H2>A kért URL nem tölthetõ le</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+Az alábbi URL nem tölthetõ le:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+A Squid az alábbi FTP parancsot küldte:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+és ezt a választ kapta
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+A hibát lehet hogy az okozta, hogy az FTP URL abszolút elérési utat tartalmaz
+(ami nem felel meg az RFC 1738 elõírásnak). Amennyiben ez a hiba oka, akkor 
+az állományt a <A HREF="%B">%B</A> címen lehet megtalálni.
 </P>
 
Index: squid/errors/Hungarian/ERR_FTP_PUT_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Hungarian/ERR_FTP_PUT_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Hungarian/ERR_FTP_PUT_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Hungarian/ERR_FTP_PUT_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,7 +1,7 @@
 <HTML><HEAD>
 <TITLE>HIBA: FTP feltöltési hiba</TITLE>
 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2"></HEAD><BODY>
-<H1>ERROR</H1>
+<H1>HIBA</H1>
 <H2>FTP PUT/feltöltés hiba</H2>
 <HR>
 <P>
Index: squid/errors/Hungarian/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Hungarian/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Hungarian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Hungarian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>HIBA: A kért URL nem tölthetõ le</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>HIBA</H1>
+<H2>A kért URL nem tölthetõ le</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+Az FTP kiszolgáló túlterheltsége miatt az alábbi URL nem tölthetõ le:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+A Squid az alábbi parancsot küldte:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+és ezt a választ kapta
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Italian/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Italian/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Italian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Italian/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERRORE: La URL richiesta non pu&ograve; essere recuperata</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>La URL richiesta non pu&ograve; essere recuperata</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Un errore di autenticazione tramite FTP &egrave; avvenuto
+mentre si cercava di recuperare la URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid ha inviato il seguente comando FTP:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+e ha ricevuto la seguente risposta: 
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Italian/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Italian/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Italian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Italian/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,21 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERRORE: La URL richiesta non pu&ograve; essere recuperata</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>La URL richiesta non pu&ograve; essere recuperata</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+La seguente URL non pu&ograve; essere recuperata:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid ha inviato il seguente comando FTP:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+e ha ricevuto la risposta: 
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+Questo potrebbe essere dovuto ad una URL FTP con un percorso assoluto
+(che non &egrave; conforme al RFC 1738). In tal caso, si pu&ograve; 
+recuperare il file in <A HREF="%B">%B</A>.
 </P>
 
Index: squid/errors/Italian/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Italian/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Italian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Italian/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,16 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERRORE: La URL richiesta non pu&ograve; essere recuperata</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>La URL richiesta non pu&ograve; essere recuperata</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+Il server FTP era troppo occupato al momento di recuperare la URL: 
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid ha inviato il seguente comando FTP: 
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+e ha ricevuto la seguente risposta: 
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Italian/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Italian/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Italian/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Italian/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERRORE: La URL richiesta non pu&ograve; essere recuperata</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>La URL richiesta non pu&ograve; essere recuperata</H2>
 <HR>
 <P>
-While trying to retrieve the URL:
+Cercando di recuperare la URL: 
 <A HREF="%U">%U</A>
 <P>
-The following error was encountered:
+&Egrave; occorso il seguente errore: 
 <UL>
 <P>
-This cache is in the process of shutting down and can not
-service your request at this time.  Please retry your
-request again soon.
+Questa cache &egrave; in fase di shutdown e non pu&ograve; 
+provvedere alla vostra richiesta in questo momento. Si prega
+di riprovare pi&ugrave; tardi. 
 </P>
Index: squid/errors/Italian/README
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Italian/README,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Italian/README	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Italian/README	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,2 +1,2 @@
-Thank you to Alessio Bragadini <alessio@dsnet.it> for
-creating these error pages in Italian!
+Thank you to Alessio Bragadini <alessio@dsnet.it> and Marco Mesturino
+<sw_tools@beatles.cselt.it> for creating these error pages in Italian!
Index: squid/errors/Slovak/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Slovak/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Slovak/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Slovak/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Pri pokuse získa» URL sa vyskytla chyba autentifikácie:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid zaslal nasledujúci FTP príkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾al nasledovnú opoveï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Slovak/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Slovak/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Slovak/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Slovak/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,21 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovane URL je nedostupne</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adované URL je nedostupné</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+Nasledovné URL je nedostupné:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid zaslal nasledujúci FTP príkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾al nasledovnú opoveï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+To mô¾e by» spôsobené uvedením absolútnej cesty v FTP URL (èo odporuje RFC
+1738). V tomto prípade by ste dokument mohli nájs» na <A HREF="%B">%B</A>.
 </P>
 
Index: squid/errors/Slovak/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Slovak/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Slovak/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Slovak/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,16 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovane URL je nedostupne</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adované URL je nedostupné</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+FTP server bol príli¹ zaneprázdnený pri pokuse získat nasledovné URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
+Squid zaslal nasledujúci FTP príkaz:
 <blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
+a obdr¾al nasledovnú opoveï:
 <blockquote><strong><pre>%F</pre></strong></blockquote>
 <blockquote><strong><pre>%g</pre></strong></blockquote>
 </P>
Index: squid/errors/Slovak/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Slovak/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Slovak/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Slovak/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
+<TITLE>CHYBA: Pozadovany dokument je nedostupny</TITLE>
 </HEAD><BODY>
-<H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H1>CHYBA</H1>
+<H2>Po¾adovaný dokument je nedostupný</H2>
 <HR>
 <P>
-While trying to retrieve the URL:
+Pri pokuse o prístup k:
 <A HREF="%U">%U</A>
 <P>
-The following error was encountered:
+do¹lo k nasledovnej chybe:
 <UL>
 <P>
-This cache is in the process of shutting down and can not
-service your request at this time.  Please retry your
-request again soon.
+Táto cache sa práve vypína a nemô¾e spracova» Va¹u po¾iadavku. Opakujte
+prosím svoju po¾iadavku za nejaký èas.
 </P>
Index: squid/errors/Spanish/ERR_ACCESS_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_ACCESS_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_ACCESS_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_ACCESS_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -15,8 +15,8 @@
 Acceso Denegado.
 </STRONG>
 <P>
-Las reglas de control de acceso impiden que su petición sea
+Las reglas de control de acceso impiden que su petici&oacute;n sea
 permitida en este momento. Contacte con su proveedor de servicios
 si cree que esto es incorrecto.
-</UL>
 </P>
+</UL>
Index: squid/errors/Spanish/ERR_CANNOT_FORWARD
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_CANNOT_FORWARD,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_CANNOT_FORWARD	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_CANNOT_FORWARD	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,18 +12,18 @@
 <UL>
 <LI>
 <STRONG>
-Imposibilidad de enviar la petición en este momento.
+Imposibilidad de enviar la petici&oacute;n en este momento.
 </STRONG>
 </UL>
 
 <P>
-La petición no ha podido ser enviada al servidor origen o a alguna
-de las cachés padres. Las razones más probables de que haya ocurrido
-este error son:
+La petici&oacute;n no ha podido ser enviada al servidor origen o a alguna
+de las cach&eacute;s padres. Las razones m&aacute;s probables de que haya 
+ocurrido este error son:
 <UL>
-<LI>El administrador de la caché no permite que esta
-    caché realice conexiones directas a los servidores
+<LI>El administrador de la cach&eacute; no permite que esta
+    cach&eacute; realice conexiones directas a los servidores
     origen, y
-<LI>Todas las cachés configuradas como padres son inalcanzables
-en este momento.
+<LI>Todas las cach&eacute;s configuradas como padres son inalcanzables
+    en este momento.
 </UL>
Index: squid/errors/Spanish/ERR_CONNECT_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_CONNECT_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_CONNECT_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_CONNECT_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,7 +12,7 @@
 <UL>
 <LI>
 <STRONG>
-Conexión fallida.
+Conexi&oacute;n fallida.
 </STRONG>
 </UL>
 
@@ -22,4 +22,4 @@
 
 <P>
 El equipo remoto o la red pueden estar fuera de servicio.
-Por favor, intente de nuevo la petición en otro momento.
+Por favor, intente de nuevo la petici&oacute;n.
Index: squid/errors/Spanish/ERR_DNS_FAIL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_DNS_FAIL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_DNS_FAIL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_DNS_FAIL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -9,11 +9,10 @@
 <P>
 Ha ocurrido el siguiente problema:
 <BLOCKQUOTE>
-Incapaz de determinar la dirección IP a partir
+Incapaz de determinar la direcci&oacute;n IP a partir
 del nombre de la máquina:
 <I>%H</I>
 </BLOCKQUOTE>
-</UL>
 
 <P>
 El programa dnsserver ha devuelto el siguiente mensaje:
@@ -24,9 +23,8 @@
 <P>
 Esto significa que:
 <PRE>
- La caché no ha sido capaz de resolver el nombre de máquina
+ La cach&eacute; no ha sido capaz de resolver el nombre de m&aacute;quina
  presente en la URL.
- Compruebe que la dirección sea correcta.
+ Compruebe que la direcci&oacute;n sea correcta.
 </PRE>
-</P>
 
Index: squid/errors/Spanish/ERR_FORWARDING_DENIED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FORWARDING_DENIED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FORWARDING_DENIED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FORWARDING_DENIED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,12 +12,12 @@
 <UL>
 <LI>
 <STRONG>
-Reenvío denegado.
+Reenv&iacute;o denegado.
 </STRONG>
 </UL>
 
 <P>
-Esta caché no permite reenviar su petición porque trata de obligar a
-mantener una relación de hermandad.
-Quizás el cliente en %i es una caché que ha sido mal configurada.
+Esta cach&eacute; no permite reenviar su petici&oacute;n porque trata de
+obligar a mantener una relaci&oacute;n de hermandad.
+Quiz&aacute;s el cliente en %i es una cach&eacute; que ha sido mal configurada.
 </P>
Index: squid/errors/Spanish/ERR_FTP_DISABLED
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FTP_DISABLED,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FTP_DISABLED	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FTP_DISABLED	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,5 +17,5 @@
 </UL>
 
 <P>
-Esta caché no proporciona servicio caché para el protocolo FTP.
+Esta cach&eacute; no proporciona servicio cach&eacute; para el protocolo FTP.
 </P>
Index: squid/errors/Spanish/ERR_FTP_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FTP_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FTP_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FTP_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -5,17 +5,13 @@
 <H2>El URL solicitado no se ha podido conseguir</H2>
 <HR>
 <P>
-Ha ocurrido un error de protocolo FTP:
-
+Ha ocurrido un error de protocolo FTP
 mientras se intentaba traer el documento con URL:
 <A HREF="%U">%U</A>
 <P>
-Squid envió la siguiente orden FTP:
+Squid envi&oacute; la siguiente orden FTP:
 <BLOCKQUOTE><PRE><STRONG>%f</STRONG></PRE></BLOCKQUOTE>
-y recibió la siguiente respuesta:
+y recibi&oacute; la siguiente respuesta:
 <BLOCKQUOTE><PRE><STRONG>%F</STRONG></PRE></BLOCKQUOTE>
 <BLOCKQUOTE><PRE><STRONG>%g</STRONG></PRE></BLOCKQUOTE>
 <P>
-Esto puede ser causado por una URL de protocolo FTP con una ruta
-de directorios absoluto(que no cumple el RFC 1738). Si esta es la
-causa, el fichero podría encontrarse en <A HREF="%B">%B</A>.
Index: squid/errors/Spanish/ERR_FTP_FORBIDDEN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FTP_FORBIDDEN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FTP_FORBIDDEN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FTP_FORBIDDEN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,18 +1,18 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERROR: El URL solicitado no se ha podido conseguir</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>El URL solicitado no se ha podido conseguir</H2>
 <HR>
 <P>
-An FTP authentication failure occurred
-while trying to retrieve the URL:
+Ha ocurrido una falla de autenticaci&oacute;n cuando se
+trataba de conseguir el URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
-<blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
-<blockquote><strong><pre>%F</pre></strong></blockquote>
-<blockquote><strong><pre>%g</pre></strong></blockquote>
-</P>
+Squid envi&oacute; el siguiente comando FTP:
+<blockquote><pre><strong>%f</strong></pre></blockquote>
+y recibi&oacute; esta respuesta
+<blockquote><pre><strong>%F</strong></pre></blockquote>
+<blockquote><pre><strong>%g</strong></pre></blockquote>
+
 
Index: squid/errors/Spanish/ERR_FTP_NOT_FOUND
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FTP_NOT_FOUND,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FTP_NOT_FOUND	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FTP_NOT_FOUND	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,21 +1,21 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERROR: El URL solicitado no se ha podido conseguir</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>El URL solicitado no se ha podido conseguir</H2>
 <HR>
 <P>
-The following URL could not be retrieved:
+El siguiente URL no pudo ser obtenido:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
-<blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
-<blockquote><strong><pre>%F</pre></strong></blockquote>
-<blockquote><strong><pre>%g</pre></strong></blockquote>
+Squid envi&oacute; el siguiente comando FTP:
+<blockquote><pre><strong>%f</strong></pre></blockquote>
+y recibi&oacute; esta respuesta
+<blockquote><pre><strong>%F</strong></pre></blockquote>
+<blockquote><pre><strong>%g</strong></pre></blockquote>
 <P>
-This might be caused by an FTP URL with an absolute path (which does
-not comply with RFC 1738).  If this is the cause, then the file
-can be found at <A HREF="%B">%B</A>.
+Esto puede ser causado por un URL FTP con un camino absoluto (y por
+lo tanto no cumple con RFC 1738). Si este es la causa, entonces el 
+archivo puede ser obtenido en <A HREF="%B">%B</A>.
 </P>
 
Index: squid/errors/Spanish/ERR_FTP_UNAVAILABLE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_FTP_UNAVAILABLE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_FTP_UNAVAILABLE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,17 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERROR: El URL solicitado no se ha podido conseguir</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>EL solicitado no se ha podido conseguir</H2>
 <HR>
 <P>
-The FTP server was too busy while trying to retrieve the URL:
+El servidor FTP estaba muy ocupado cuando se intentaba obtener el URL:
 <A HREF="%U">%U</A>
 <P>
-Squid sent the following FTP command:
-<blockquote><strong><pre>%f</pre></strong></blockquote>
-and then received this reply
-<blockquote><strong><pre>%F</pre></strong></blockquote>
-<blockquote><strong><pre>%g</pre></strong></blockquote>
-</P>
+Squid envi&oacute; el siguiente comando FTP:
+<blockquote><pre><strong>%f</strong></pre></blockquote>
+y recibi&oacute; esta respuesta
+<blockquote><pre><strong>%F</strong></pre></blockquote>
+<blockquote><pre><strong>%g</strong></pre></blockquote>
+
 
Index: squid/errors/Spanish/ERR_INVALID_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_INVALID_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_INVALID_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_INVALID_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -14,19 +14,21 @@
 <UL>
 <LI>
 <STRONG>
-Petición no válida.
+Petici&oacute;n no v&aacute;lida.
 </STRONG>
 </UL>
 
 <P>
-Algún aspecto de la petición HTTP no es válido. Posibles problemas:
+Alg&uacute;n aspecto de la petici&oacute;n HTTP no es v&aacute;lido. 
+Posibles problemas:
 <UL>
-<LI>Falta o es desconocido el método de la petición (no es GET ni POST)
+<LI>Falta o es desconocido el m&eacute;todo de la petici&oacute;n (no es 
+    GET ni POST)
 <LI>Falta el URL
 <LI>Falta el identificador HTTP (HTTP/1.0)
-<LI>La petición es demasiado grande.
-<LI>Hay caracteres ilegales en el nombre de máquina;
-    el carácter  subrayado (_) no está permitido.
+<LI>La petici&oacute;n es demasiado grande.
+<LI>Hay caracteres ilegales en el nombre de m&aacute;quina;
+    el car&aacute;cter subrayado (_) no est&aacute; permitido.
 </UL>
-</P>
+
 
Index: squid/errors/Spanish/ERR_INVALID_URL
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_INVALID_URL,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_INVALID_URL	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_INVALID_URL	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,12 +17,12 @@
 </UL>
 
 <P>
-Algún aspecto del URL solicitado es incorrecto. Posibles problemas:
+Alg&uacute;n aspecto del URL solicitado es incorrecto. Posibles problemas:
 <UL>
-<LI>Falta o es incorrecto el protocolo de acceso (debe ser `http://'' o similar)
-<LI>Falta el nombre de la máquina
-<LI>Hay un doble-escape ilegas en la ruta de la URL
-<LI>Hay caracteres ilegales en el nombre de máquina;
-    el caracter de subrayado no está permitido
+<LI>Falta o es incorrecto el protocolo de acceso (debe ser ``http://'' o 
+    similar)
+<LI>Falta el nombre de la m&aacute;quina
+<LI>Hay un doble-escape ilegal en la ruta de la URL
+<LI>Hay caracteres ilegales en el nombre de m&aacute;quina;
+    el caracter de subrayado (_) no est&aacute; permitido
 </UL>
-</P>
Index: squid/errors/Spanish/ERR_LIFETIME_EXP
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_LIFETIME_EXP,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_LIFETIME_EXP	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_LIFETIME_EXP	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,12 +12,12 @@
 <UL>
 <LI>
 <STRONG>
-Ha expirado el tiempo de vida de la conexión
+Ha expirado el tiempo de vida de la conexi&oacute;n
 </STRONG>
 </UL>
 
 <P>
-Squid ha dado por terminada la petición porque se ha excedido
-el tiempo de vida máximo para una conexión.
+Squid ha dado por terminada la petici&oacute;n porque se ha excedido
+el tiempo de vida m&aacute;ximo para una conexi&oacute;n.
 </P>
 
Index: squid/errors/Spanish/ERR_NO_RELAY
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_NO_RELAY,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_NO_RELAY	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_NO_RELAY	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,5 +17,5 @@
 </UL>
 
 <P>
-Esta caché no tiene definido ninguna pasarela para el protocolo WAIS !!
-¡Gríteselo al administrador de la caché !
+Esta cach&eacute; no tiene definido ninguna pasarela para el protocolo WAIS !!
+&iexcl;Gr&iacute;teselo al administrador de la cach&eacute; !
Index: squid/errors/Spanish/ERR_READ_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_READ_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_READ_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_READ_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -19,9 +19,8 @@
 <P>
 El sistema ha devuelto el siguiente mensaje:
 <PRE><I>    %E</I></PRE>
-</P>
 
 <P>
-Ha ocurrido algún problema mientras se leían datos de la red.
-Por favor, inténtelo de nuevo.
+Ha ocurrido alg&uacute;n problema mientras se le&iacute;an datos de la red.
+Por favor, int&eacute;ntelo de nuevo.
 </P>
Index: squid/errors/Spanish/ERR_READ_TIMEOUT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_READ_TIMEOUT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_READ_TIMEOUT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_READ_TIMEOUT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,7 +12,7 @@
 <UL>
 <LI>
 <STRONG>
-Se acabó el tiempo máximo para lectura de datos de la red.
+Se acab&oacute; el tiempo m&aacute;ximo para lectura de datos de la red.
 </STRONG>
 </UL>
 
@@ -21,6 +21,7 @@
 <PRE><I>    %E</I></PRE>
 
 <P>
-Se acabó el tiempo máximo de lectura mientras se leían datos de la red.
-La red o el servidor pueden estar congestionados. Por favor, inténtelo de nuevo
+Se acab&oacute; el tiempo m&aacute;ximo de lectura mientras se le&iacute;an
+datos de la red. La red o el servidor pueden estar congestionados. Por 
+favor, int&eacute;ntelo de nuevo
 </P>
Index: squid/errors/Spanish/ERR_SHUTTING_DOWN
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_SHUTTING_DOWN,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_SHUTTING_DOWN	26 Jan 2000 03:23:10 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_SHUTTING_DOWN	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,17 +1,18 @@
 <HTML><HEAD>
-<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<TITLE>ERROR: El URL solicitado no se ha podido conseguir</TITLE>
 </HEAD><BODY>
 <H1>ERROR</H1>
-<H2>The requested URL could not be retrieved</H2>
+<H2>El URL solicitado no se ha podido conseguir</H2>
 <HR>
 <P>
-While trying to retrieve the URL:
+Mientras se intentaba traer el URL:
 <A HREF="%U">%U</A>
 <P>
-The following error was encountered:
+Ha ocurrido el siguiente problema:
 <UL>
-<P>
-This cache is in the process of shutting down and can not
-service your request at this time.  Please retry your
-request again soon.
-</P>
+
+Esta cach&eacute; esta siendo desactivado y no puede atender su
+solicitud en este momento. Por favor reintente su solicitud
+nuevamente m&aacute;s tarde.
+
+</UL>
Index: squid/errors/Spanish/ERR_SOCKET_FAILURE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_SOCKET_FAILURE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_SOCKET_FAILURE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_SOCKET_FAILURE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -22,4 +22,4 @@
 
 <P>
 Squid ha sido incapaz de crear un puerto TCP, posiblemente debido
-al exceso de carga. Inténtelo de nuevo, por favor.
+al exceso de carga. Int&eacute;ntelo de nuevo, por favor.
Index: squid/errors/Spanish/ERR_UNSUP_REQ
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_UNSUP_REQ,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_UNSUP_REQ	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_UNSUP_REQ	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,10 +12,10 @@
 <UL>
 <LI>
 <STRONG>
-Método de la petición y protocolo no soportados
+M&eacute;todo de la petici&oacute;n y protocolo no soportados
 </STRONG>
 </UL>
 
 <P>
-Squid no admite todos los métodos para todos los protocolos de acceso.
+Squid no admite todos los m&eacute;todos para todos los protocolos de acceso.
 Por ejemplo, no se puede hacer un POST a un servidor Gopher.
Index: squid/errors/Spanish/ERR_URN_RESOLVE
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_URN_RESOLVE,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_URN_RESOLVE	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_URN_RESOLVE	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -17,5 +17,5 @@
 </UL>
 
 <P>
-Hey, no espere mucho sobre URNs en %T :)
+Hey, no espere mucho de URNs en %T :)
 </P>
Index: squid/errors/Spanish/ERR_WRITE_ERROR
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_WRITE_ERROR,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_WRITE_ERROR	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_WRITE_ERROR	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -21,5 +21,5 @@
 <PRE><I>    %E</I></PRE>
 
 <P>
-Se ha producido un error mientras se escribían datos en la red.
-Por favor, inténtelo de nuevo.
+Se ha producido un error mientras se escrib&iacute;an datos en la red.
+Por favor, int&eacute;ntelo de nuevo.
Index: squid/errors/Spanish/ERR_ZERO_SIZE_OBJECT
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/ERR_ZERO_SIZE_OBJECT,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/ERR_ZERO_SIZE_OBJECT	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -12,10 +12,11 @@
 <UL>
 <LI>
 <STRONG>
-Respuesta vacía (tamaño cero)
+Respuesta vac&iacute;a (tama&ntilde;o cero)
 </STRONG>
 </UL>
 
 <P>
-Squid no ha recibido ninguna información en respuesta a esta petición.
+Squid no ha recibido ninguna informaci&oacute;n en respuesta a esta 
+petici&oacute;n.
 </P>
Index: squid/errors/Spanish/README
===================================================================
RCS file: /cvsroot/squid-sf//squid/errors/Spanish/README,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/errors/Spanish/README	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/errors/Spanish/README	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,3 @@
-Thanks to Javier Puche <javier.puche@rediris.es>,
-and Roberto Lumbreras <rover-squid@lander.es>
+Thanks to Javier Puche <javier.puche@rediris.es>, Roberto Lumbreras
+<rover-squid@lander.es>, and Juan Nicolas Ruiz N. <nicolas@ula.ve>
 for creating these error pages in Spanish!
-
-Note: character set is ISO-LATIN-1
Index: squid/icons/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/icons/Attic/Makefile.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/icons/Makefile.in	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/icons/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+# $Id: Makefile.in,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
 #
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
Index: squid/include/autoconf.h.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/autoconf.h.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/include/autoconf.h.in	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/include/autoconf.h.in	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -70,6 +70,9 @@
 /* Define to use async disk I/O operations */
 #undef USE_ASYNC_IO
 
+/* Defines how many threads to use for async I/O */
+#undef NUMTHREADS
+
 /*
  * If you want to use Squid's ICMP features (highly recommended!) then
  * define this.  When USE_ICMP is defined, Squid will send ICMP pings
@@ -105,6 +108,11 @@
 #undef SQUID_SNMP
 
 /*
+ * Define to enable WCCP
+ */
+#define USE_WCCP 1
+
+/*
  * Squid frequently calls gettimeofday() for accurate timestamping.
  * If you are concerned that gettimeofday() is called too often, and
  * could be causing performance degradation, then you can define
@@ -247,10 +255,31 @@
 #undef HAVE_STATVFS
 
 /*
- * we check for struct mallinfo
+ * If --disable-internal-dns was given to configure, then we'll use
+ * the dnsserver processes instead.
+ */
+#undef USE_DNSSERVERS
+
+/*
+ * we check for the existance of struct mallinfo
  */
 #undef HAVE_STRUCT_MALLINFO
 
+/*
+ * Do we want to use truncate(2) or unlink(2)?
+ */
+#undef USE_TRUNCATE
+
+/*
+ * Allow underscores in host names
+ */
+#undef ALLOW_HOSTNAME_UNDERSCORES
+
+/*
+ * Use the heap-based replacement techniques
+ */
+#undef HEAP_REPLACEMENT
+
 /* The number of bytes in a int.  */
 #undef SIZEOF_INT
 
@@ -350,6 +379,9 @@
 /* Define if you have the seteuid function.  */
 #undef HAVE_SETEUID
 
+/* Define if you have the setgroups function.  */
+#undef HAVE_SETGROUPS
+
 /* Define if you have the setpgrp function.  */
 #undef HAVE_SETPGRP
 
Index: squid/include/cache_snmp.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/cache_snmp.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/include/cache_snmp.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/include/cache_snmp.h	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: cache_snmp.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: cache_snmp.h,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  */
 
 #ifdef SQUID_SNMP
@@ -25,12 +25,12 @@
 
 /* MIB definitions
  * SQUID-MIB
- * 	.iso.org.dod.internet.private.enterprises.nlanr.squid
- *	  1   3   6     1        4         1      3495    1
+ *      .iso.org.dod.internet.private.enterprises.nlanr.squid
+ *        1   3   6     1        4         1      3495    1
  *
  * PROXY-MIB
- *	.iso.org.dod.internet.experimental.nsfnet.proxy
- *	  1   3   6     1          3         25    17
+ *      .iso.org.dod.internet.experimental.nsfnet.proxy
+ *        1   3   6     1          3         25    17
  */
 
 #define SQUIDMIB 1, 3, 6, 1, 4, 1, 3495, 1
@@ -53,8 +53,8 @@
 #define LEN_SQ_MESH LEN_SQUIDMIB+1
 
 /* 
-	cacheSystem group 
-*/
+ * cacheSystem group 
+ */
 
 enum {
     SYS_START,
@@ -68,8 +68,8 @@
 #define LEN_SYS_INST LEN_SQ_SYS + 2
 
 /* 
-	cacheConfig group 
-*/
+ * cacheConfig group 
+ */
 
 enum {
     CONF_START,
@@ -97,8 +97,8 @@
 #define LEN_CONF_ST_INST LEN_CONF + 2
 
 /* 
-	cacheMesh group 
-*/
+ * cacheMesh group 
+ */
 
 enum {
     MESH_START,
@@ -140,8 +140,8 @@
 };
 
 /* 
-	cacheNetwork group 
-*/
+ * cacheNetwork group 
+ */
 
 enum {
     NET_START,
@@ -185,8 +185,8 @@
 };
 
 /* 
-	Cache Performance Group 
-*/
+ * Cache Performance Group 
+ */
 
 enum {
     PERF_START,
Index: squid/include/config.h.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/config.h.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/include/config.h.in	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/include/config.h.in	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: config.h.in,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: config.h.in,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -100,6 +100,9 @@
 #elif defined(__CYGWIN32__) || defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
 #define _SQUID_MSWIN_
 
+#elif defined(__APPLE__)
+#define _SQUID_APPLE_
+
 #elif defined(sony_news) && defined(__svr4)
 #define _SQUID_NEWSOS6_
 
@@ -162,12 +165,6 @@
 #define xislower(x) islower((unsigned char)x)
 #define xisalpha(x) isalpha((unsigned char)x)
 
-#if defined(O_NONBLOCK) && !defined(_SQUID_SUNOS_) && !defined(_SQUID_SOLARIS_)
-#define SQUID_NONBLOCK O_NONBLOCK
-#else
-#define SQUID_NONBLOCK O_NDELAY
-#endif
-
 #if HAVE_RANDOM
 #define squid_random random
 #define squid_srandom srandom
Index: squid/include/heap.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/heap.h,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/include/heap.h	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/include/heap.h	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,5 +1,5 @@
 /*
- * $Id: heap.h,v 1.1 2000/01/26 03:25:00 hno Exp $
+ * $Id: heap.h,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: John Dilley, Hewlett Packard
  *
Index: squid/include/rfc1035.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/rfc1035.h,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/include/rfc1035.h	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/include/rfc1035.h	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,5 +1,5 @@
 /*
- * $Id: rfc1035.h,v 1.1 2000/01/26 03:25:00 hno Exp $
+ * $Id: rfc1035.h,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: Harvest Derived
  *
Index: squid/include/snmp_vars.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/snmp_vars.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/include/snmp_vars.h	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/include/snmp_vars.h	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -26,7 +26,7 @@
  * 
  * Author: Ryan Troll <ryan+@andrew.cmu.edu>
  * 
- * $Id: snmp_vars.h,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: snmp_vars.h,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  * 
  **********************************************************************/
 
@@ -48,6 +48,7 @@
 #endif
 
     struct variable_list *snmp_var_new(oid *, int);
+    struct variable_list *snmp_var_new_integer(oid *, int, int, unsigned char);
     struct variable_list *snmp_var_clone(struct variable_list *);
     void snmp_var_free(struct variable_list *);
 
@@ -58,8 +59,7 @@
 }
 
 #endif
-#define MAX_NAME_LEN	64	/* number of subid's in a objid *//*      *RFC 1902:Structure of Management Information for SNMPv2
-*
+#define MAX_NAME_LEN	64	/* number of subid's in a objid *//*      *RFC 1902:Structure of Management Information for SNMPv2      *
       *Defined Types
 *
       */
Index: squid/include/splay.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/splay.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/include/splay.h	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/include/splay.h	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: splay.h,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: splay.h,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  */
 
 
@@ -9,8 +9,8 @@
     struct _splay_node *right;
 } splayNode;
 
-typedef int SPLAYCMP(const void *, splayNode *);
-typedef void SPLAYWALKEE(void *, void *);
+typedef int SPLAYCMP(const void *a, const void *b);
+typedef void SPLAYWALKEE(void *nodedata, void *state);
 typedef void SPLAYFREE(void *);
 
 extern int splayLastResult;
Index: squid/include/util.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/util.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/include/util.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/include/util.h	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: util.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: util.h,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: Harvest Derived
  *
@@ -80,6 +80,8 @@
 
 /* rfc1738.c */
 extern char *rfc1738_escape(const char *);
+extern char *rfc1738_escape_unescaped(const char *);
+extern char *rfc1738_escape_part(const char *);
 extern void rfc1738_unescape(char *);
 
 #if XMALLOC_STATISTICS
Index: squid/include/version.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/version.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/include/version.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/include/version.h	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,12 +1,12 @@
 /*
- * $Id: version.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: version.h,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  *  SQUID_VERSION - String for version id of this distribution
  */
 #ifndef SQUID_VERSION
-#define SQUID_VERSION	"2.2.STABLE5"
+#define SQUID_VERSION	"2.3.STABLE1"
 #endif
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 938113298
+#define SQUID_RELEASE_TIME 947484665
 #endif
Index: squid/lib/Array.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/Array.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/Array.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/Array.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: Array.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: Array.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: Alex Rousskov
  *
@@ -89,7 +89,7 @@
 {
     assert(a);
     if (a->count >= a->capacity)
-	arrayGrow(a, a->count+1);
+	arrayGrow(a, a->count + 1);
     a->items[a->count++] = obj;
 }
 
@@ -111,15 +111,15 @@
     assert(a->capacity < min_capacity);
     delta = min_capacity;
     /* make delta a multiple of min_delta */
-    delta += min_delta-1;
+    delta += min_delta - 1;
     delta /= min_delta;
     delta *= min_delta;
     /* actual grow */
     assert(delta > 0);
     a->capacity += delta;
     a->items = a->items ?
-	xrealloc(a->items, a->capacity * sizeof(void*)) :
-	xmalloc(a->capacity * sizeof(void*));
+	xrealloc(a->items, a->capacity * sizeof(void *)) :
+         xmalloc(a->capacity * sizeof(void *));
     /* reset, just in case */
-    memset(a->items+a->count, 0, (a->capacity-a->count) * sizeof(void*));
+    memset(a->items + a->count, 0, (a->capacity - a->count) * sizeof(void *));
 }
Index: squid/lib/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/Attic/Makefile.in,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/Makefile.in	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/Makefile.in	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 #
-#  $Id: Makefile.in,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+#  $Id: Makefile.in,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
 #
 prefix		= @prefix@
 top_srcdir	= @top_srcdir@
@@ -23,6 +23,7 @@
 INCLUDE		= -I../include -I$(top_srcdir)/include
 UTILOBJS	= rfc1123.o \
 		  rfc1738.o \
+		  rfc1035.o \
 		  util.o \
 		  getfullhostname.o \
 		  base64.o \
@@ -37,6 +38,7 @@
 		  Array.o \
 		  Stack.o \
 		  hash.o \
+		  heap.o \
 		  $(LIBOBJS)
 REGEXOBJS	= GNUregex.o
 DLMALLOCOBJS	= dlmalloc.o
@@ -68,7 +70,7 @@
 
 distclean: clean
 	-rm -f libregex.a
-	-rm -f Makefile
+	-rm -f Makefile Makefile.bak
 
 install: all
 
Index: squid/lib/Stack.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/Stack.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/Stack.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/Stack.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: Stack.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: Stack.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: Alex Rousskov
  *
@@ -55,8 +55,8 @@
 }
 
 void *
-stackTop(Stack *s)
+stackTop(Stack * s)
 {
     assert(s);
-    return s->count ? s->items[s->count-1] : NULL;
+    return s->count ? s->items[s->count - 1] : NULL;
 }
Index: squid/lib/drand48.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/drand48.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/drand48.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/drand48.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,6 +1,8 @@
+
+
 /* borrowed from libc/misc/drand48.c in Linux libc-5.4.46 this quick
-   hack by Martin Hamilton <martinh@gnu.org> to make Squid build on
-   Win32 with GNU-Win32 - sorry, folks! */
+ * hack by Martin Hamilton <martinh@gnu.org> to make Squid build on
+ * Win32 with GNU-Win32 - sorry, folks! */
 
 #ifndef HAVE_DRAND48
 
@@ -20,34 +22,36 @@
 #define A2	0x5
 #define C	0xB
 
-static void next( void );
-static unsigned x[3] = { X0, X1, X2 }, a[3] = { A0, A1, A2 }, c = C;
+static void next(void);
+static unsigned x[3] =
+{X0, X1, X2}, a[3] =
+{A0, A1, A2}, c = C;
 
-double drand48( void );
+double drand48(void);
 
 double
-drand48( void )
+drand48(void)
 {
-	static double two16m = 1.0 / (1L << N);
-	next();
-	return (two16m * (two16m * (two16m * x[0] + x[1]) + x[2]));
+    static double two16m = 1.0 / (1L << N);
+    next();
+    return (two16m * (two16m * (two16m * x[0] + x[1]) + x[2]));
 }
 
 static void
-next( void )
+next(void)
 {
-	unsigned p[2], q[2], r[2], carry0, carry1;
+    unsigned p[2], q[2], r[2], carry0, carry1;
 
-	MUL(a[0], x[0], p);
-	ADDEQU(p[0], c, carry0);
-	ADDEQU(p[1], carry0, carry1);
-	MUL(a[0], x[1], q);
-	ADDEQU(p[1], q[0], carry0);
-	MUL(a[1], x[0], r);
-	x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] +
-		a[0] * x[2] + a[1] * x[1] + a[2] * x[0]);
-	x[1] = LOW(p[1] + r[0]);
-	x[0] = LOW(p[0]);
+    MUL(a[0], x[0], p);
+    ADDEQU(p[0], c, carry0);
+    ADDEQU(p[1], carry0, carry1);
+    MUL(a[0], x[1], q);
+    ADDEQU(p[1], q[0], carry0);
+    MUL(a[1], x[0], r);
+    x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] +
+	a[0] * x[2] + a[1] * x[1] + a[2] * x[0]);
+    x[1] = LOW(p[1] + r[0]);
+    x[0] = LOW(p[0]);
 }
 
 #endif /* HAVE_DRAND48 */
Index: squid/lib/hash.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/hash.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/lib/hash.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/lib/hash.c	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: hash.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: hash.c,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  * DEBUG: section 0     Hash Tables
  * AUTHOR: Harvest Derived
@@ -309,7 +309,7 @@
 {
     assert(hid);
     if (hid->buckets)
-        xfree(hid->buckets);
+	xfree(hid->buckets);
     xfree(hid);
 }
 
Index: squid/lib/heap.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/heap.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/lib/heap.c	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/lib/heap.c	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: heap.c,v 1.1 2000/01/26 03:25:00 hno Exp $
+ * $Id: heap.c,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
  *
  * AUTHOR: John Dilley, Hewlett Packard
  *
Index: squid/lib/md5.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/md5.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/md5.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/md5.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: md5.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: md5.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  */
 
 /* taken from RFC-1321/Appendix A.3 */
@@ -358,4 +358,5 @@
     for (i = 0; i < len; i++)
 	output[i] = (char) value;
 }
+
 #endif
Index: squid/lib/rfc1035.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/rfc1035.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/lib/rfc1035.c	26 Jan 2000 03:25:00 -0000	1.1
+++ squid/lib/rfc1035.c	26 Jan 2000 03:25:00 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: rfc1035.c,v 1.1 2000/01/26 03:25:00 hno Exp $
+ * $Id: rfc1035.c,v 1.1.1.1 2000/01/26 03:25:00 hno Exp $
  *
  * Low level DNS protocol routines
  * AUTHOR: Duane Wessels
Index: squid/lib/rfc1123.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/rfc1123.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/lib/rfc1123.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/lib/rfc1123.c	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: rfc1123.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: rfc1123.c,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  * DEBUG: 
  * AUTHOR: Harvest Derived
@@ -119,7 +119,7 @@
 	s++;			/* or: Thu, 10 Jan 1993 01:29:59 GMT */
 	while (*s == ' ')
 	    s++;
-	if (xisdigit(*s) && !xisdigit(*(s+1))) /* backoff if only one digit */
+	if (xisdigit(*s) && !xisdigit(*(s + 1)))	/* backoff if only one digit */
 	    s--;
 	if (strchr(s, '-')) {	/* First format */
 	    if ((int) strlen(s) < 18)
@@ -237,16 +237,17 @@
     gmt_yday = gmt->tm_yday;
 
     lt = localtime(t);
-    day_offset = lt->tm_yday - gmt_yday;
-    min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
-	+ (lt->tm_min - gmt_min);
 
+    day_offset = lt->tm_yday - gmt_yday;
     /* wrap round on end of year */
     if (day_offset > 1)
 	day_offset = -1;
     else if (day_offset < -1)
 	day_offset = 1;
 
+    min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
+	+ (lt->tm_min - gmt_min);
+
     len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt);
     snprintf(buf + len, 128 - len, "%+03d%02d",
 	(min_offset / 60) % 24,
Index: squid/lib/rfc1738.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/rfc1738.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/rfc1738.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/rfc1738.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: rfc1738.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: rfc1738.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  *
  * DEBUG: 
  * AUTHOR: Harvest Derived
@@ -54,7 +54,9 @@
     (char) 0x3E,		/* > */
     (char) 0x22,		/* " */
     (char) 0x23,		/* # */
+#if 0				/* done in code */
     (char) 0x25,		/* % */
+#endif
     (char) 0x7B,		/* { */
     (char) 0x7D,		/* } */
     (char) 0x7C,		/* | */
@@ -68,12 +70,23 @@
     (char) 0x20			/* space */
 };
 
+static char rfc1738_reserved_chars[] =
+{
+    (char) 0x3b,		/* ; */
+    (char) 0x2f,		/* / */
+    (char) 0x3f,		/* ? */
+    (char) 0x3a,		/* : */
+    (char) 0x40,		/* @ */
+    (char) 0x3d,		/* = */
+    (char) 0x26			/* & */
+};
+
 /*
  *  rfc1738_escape - Returns a static buffer contains the RFC 1738 
  *  compliant, escaped version of the given url.
  */
-char *
-rfc1738_escape(const char *url)
+static char *
+rfc1738_do_escape(const char *url, int encode_reserved)
 {
     static char *buf;
     static size_t bufsize = 0;
@@ -96,6 +109,16 @@
 		break;
 	    }
 	}
+	/* Handle % separately */
+	if (encode_reserved >= 0 && *p == '%')
+	    do_escape = 1;
+	/* RFC 1738 defines these chars as reserved */
+	for (i = 0; i < sizeof(rfc1738_reserved_chars) && encode_reserved > 0; i++) {
+	    if (*p == rfc1738_reserved_chars[i]) {
+		do_escape = 1;
+		break;
+	    }
+	}
 	/* RFC 1738 says any control chars (0x00-0x1F) are encoded */
 	if ((unsigned char) *p <= (unsigned char) 0x1F) {
 	    do_escape = 1;
@@ -125,6 +148,36 @@
 }
 
 /*
+ * rfc1738_escape - Returns a static buffer that contains the RFC
+ * 1738 compliant, escaped version of the given url.
+ */
+char *
+rfc1738_escape(const char *url)
+{
+    return rfc1738_do_escape(url, 0);
+}
+
+/*
+ * rfc1738_escape_unescaped - Returns a static buffer that contains
+ * the RFC 1738 compliant, escaped version of the given url.
+ */
+char *
+rfc1738_escape_unescaped(const char *url)
+{
+    return rfc1738_do_escape(url, -1);
+}
+
+/*
+ * rfc1738_escape_part - Returns a static buffer that contains the
+ * RFC 1738 compliant, escaped version of the given url segment.
+ */
+char *
+rfc1738_escape_part(const char *url)
+{
+    return rfc1738_do_escape(url, 1);
+}
+
+/*
  *  rfc1738_unescape() - Converts escaped characters (%xy numbers) in 
  *  given the string.  %% is a %. %ab is the 8-bit hexadecimal number "ab"
  */
@@ -138,16 +191,16 @@
 	s[i] = s[j];
 	if (s[i] != '%')
 	    continue;
-	if (s[j+1] == '%') {	/* %% case */
+	if (s[j + 1] == '%') {	/* %% case */
 	    j++;
 	    continue;
 	}
-	if (s[j+1] && s[j+2]) {
-	    hexnum[0] = s[j+1];
-	    hexnum[1] = s[j+2];
+	if (s[j + 1] && s[j + 2]) {
+	    hexnum[0] = s[j + 1];
+	    hexnum[1] = s[j + 2];
 	    hexnum[2] = '\0';
 	    if (1 == sscanf(hexnum, "%x", &x)) {
-	        s[i] = (char) (0x0ff & x);
+		s[i] = (char) (0x0ff & x);
 		j += 2;
 	    }
 	}
Index: squid/lib/safe_inet_addr.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/safe_inet_addr.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/lib/safe_inet_addr.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/lib/safe_inet_addr.c	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,5 +1,6 @@
+
 /*
- * $Id: safe_inet_addr.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: safe_inet_addr.c,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  */
 
 #include "config.h"
Index: squid/lib/snprintf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/snprintf.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/lib/snprintf.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/lib/snprintf.c	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: snprintf.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: snprintf.c,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  */
 
 /* ====================================================================
Index: squid/lib/splay.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/splay.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/splay.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/splay.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,5 +1,5 @@
 /*
- * $Id: splay.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: splay.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  */
 
 #include "config.h"
@@ -59,11 +59,11 @@
     l = r = &N;
 
     for (;;) {
-	splayLastResult = compare(data, top);
+	splayLastResult = compare(data, top->data);
 	if (splayLastResult < 0) {
 	    if (top->left == NULL)
 		break;
-	    if ((splayLastResult = compare(data, top->left)) < 0) {
+	    if ((splayLastResult = compare(data, top->left->data)) < 0) {
 		y = top->left;	/* rotate right */
 		top->left = y->right;
 		y->right = top;
@@ -77,7 +77,7 @@
 	} else if (splayLastResult > 0) {
 	    if (top->right == NULL)
 		break;
-	    if ((splayLastResult = compare(data, top->right)) > 0) {
+	    if ((splayLastResult = compare(data, top->right->data)) > 0) {
 		y = top->right;	/* rotate left */
 		top->right = y->left;
 		y->left = top;
@@ -100,7 +100,7 @@
 }
 
 void
-splay_destroy(splayNode * top, SPLAYFREE *free_func)
+splay_destroy(splayNode * top, SPLAYFREE * free_func)
 {
     if (top->left)
 	splay_destroy(top->left, free_func);
@@ -111,29 +111,43 @@
 }
 
 void
-splay_walk(splayNode *top, SPLAYWALKEE *walkee, void *state)
+splay_walk(splayNode * top, SPLAYWALKEE * walkee, void *state)
 {
     if (top->left)
 	splay_walk(top->left, walkee, state);
+    walkee(top->data, state);
     if (top->right)
 	splay_walk(top->right, walkee, state);
-    walkee(top->data, state);
 }
 
+#ifdef DEBUG
+void
+splay_dump_entry(void *data, int depth)
+{
+    printf("%*s%s\n", depth, "", (char *) data);
+}
 
-
-#ifdef DRIVER
+static void
+splay_do_dump(splayNode * top, void printfunc(void *data, int depth), int depth)
+{
+    if (!top)
+	return;
+    splay_do_dump(top->left, printfunc, depth + 1);
+    printfunc(top->data, depth);
+    splay_do_dump(top->right, printfunc, depth + 1);
+}
 
 void
-splay_print(splayNode * top, void (*printfunc) ())
+splay_dump(splayNode * top, void printfunc(void *data, int depth))
 {
-    if (top == NULL)
-	return;
-    splay_print(top->left, printfunc);
-    printfunc(top->data);
-    splay_print(top->right, printfunc);
+    splay_do_dump(top, printfunc, 0);
 }
 
+
+#endif
+
+#ifdef DRIVER
+
 typedef struct {
     int i;
 } intnode;
@@ -147,10 +161,10 @@
 }
 
 void
-printint(void *a)
+printint(void *a, void *state)
 {
     intnode *A = a;
-    printf("%d\n", A->i);
+    printf("%d\n", "", A->i);
 }
 
 main(int argc, char *argv[])
@@ -164,7 +178,7 @@
 	I->i = random();
 	top = splay_insert(I, top, compareint);
     }
-    splay_print(top, printint);
+    splay_walk(top, printint, NULL);
     return 0;
 }
 #endif /* DRIVER */
Index: squid/lib/stub_memaccount.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/stub_memaccount.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/lib/stub_memaccount.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/lib/stub_memaccount.c	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -1,10 +1,10 @@
 /*
- * $Id: stub_memaccount.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: stub_memaccount.c,v 1.1.1.2 2000/01/26 03:25:00 hno Exp $
  */
 
 /* Stub function for programs not implementing statMemoryAccounted */
 #include <config.h>
-int 
+int
 statMemoryAccounted(void)
 {
     return -1;
Index: squid/lib/util.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/util.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/lib/util.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/lib/util.c	26 Jan 2000 03:25:00 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: util.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: util.c,v 1.1.1.3 2000/01/26 03:25:00 hno Exp $
  *
  * DEBUG: 
  * AUTHOR: Harvest Derived
@@ -700,7 +700,7 @@
     return (int) rint(xpercent(part, whole));
 #else
     /* SCO 3.2v4.2 doesn't have rint() -- mauri@mbp.ee */
-    return (int) floor(xpercent(part, whole)+0.5);
+    return (int) floor(xpercent(part, whole) + 0.5);
 #endif
 }
 
@@ -715,7 +715,7 @@
 const char *
 xitoa(int num)
 {
-    static char buf[24]; /* 2^64 = 18446744073709551616 */
+    static char buf[24];	/* 2^64 = 18446744073709551616 */
     snprintf(buf, sizeof(buf), "%d", num);
     return buf;
 }
Index: squid/scripts/access-log-matrix.pl
===================================================================
RCS file: /cvsroot/squid-sf//squid/scripts/access-log-matrix.pl,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/scripts/access-log-matrix.pl	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/scripts/access-log-matrix.pl	26 Jan 2000 03:25:00 -0000	1.1.1.2
@@ -47,9 +47,9 @@
 
 print  '       HOSTNAME: '. `hostname`;
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdat) = localtime($first);
-printf "FIRST LOG ENTRY: %s/%s/%s %.2d:%.2d:%.2d\n", $year,$mon+1,$mday, $hour,$min,$sec;
+printf "FIRST LOG ENTRY: %04d/%02d/%02d %.2d:%.2d:%.2d\n", $year+1900,$mon+1,$mday, $hour,$min,$sec;
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdat) = localtime($last);
-printf " LAST LOG ENTRY: %s/%s/%s %.2d:%.2d:%.2d\n", $year,$mon+1,$mday, $hour,$min,$sec;
+printf " LAST LOG ENTRY: %04d/%02d/%02d %.2d:%.2d:%.2d\n", $year+1900,$mon+1,$mday, $hour,$min,$sec;
 print "\n";
 
 printf ("%25.25s %5s %5s %5s %5s %5s %5s %5s %5s\n",
Index: squid/snmplib/snmp_vars.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/snmplib/snmp_vars.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/snmplib/snmp_vars.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/snmplib/snmp_vars.c	26 Jan 2000 03:25:01 -0000	1.1.1.2
@@ -115,7 +115,8 @@
     printf("VARS: Creating.\n");
 #endif
 
-    New = (struct variable_list *) xmalloc(sizeof(struct variable_list));
+    New = xmalloc(sizeof(*New));
+    /* XXX xmalloc never returns NULL */
     if (New == NULL) {
 	snmp_set_api_error(SNMPERR_OS_ERR);
 	return (NULL);
@@ -131,6 +132,7 @@
 	return (New);
     }
     New->name = (oid *) xmalloc(Len * sizeof(oid));
+    /* XXX xmalloc never returns NULL */
     if (New->name == NULL) {
 	xfree(New);
 	snmp_set_api_error(SNMPERR_OS_ERR);
@@ -147,6 +149,17 @@
     return (New);
 }
 
+struct variable_list *
+snmp_var_new_integer(oid * Name, int Len, int ival, unsigned char type)
+{
+    variable_list *v = snmp_var_new(Name, Len);
+    v->val_len = sizeof(int);
+    v->val.integer = xmalloc(sizeof(int));
+    v->type = type;
+    *(v->val.integer) = ival;
+    return v;
+}
+
 /* Clone a variable list.
  *
  * Returns NULL upon error.
@@ -214,7 +227,7 @@
 
 /* Free a variable_list.
  */
-void 
+void
 snmp_var_free(struct variable_list *Ptr)
 {
     if (Ptr->name && Ptr->name_length > 0)
Index: squid/src/HttpHdrCc.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHdrCc.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHdrCc.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHdrCc.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHdrCc.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHdrCc.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 65    HTTP Cache Control Header
  * AUTHOR: Alex Rousskov
@@ -47,6 +47,7 @@
     {"proxy-revalidate", CC_PROXY_REVALIDATE},
     {"only-if-cached", CC_ONLY_IF_CACHED},
     {"max-age", CC_MAX_AGE},
+    {"s-maxage", CC_S_MAXAGE},
     {"Other,", CC_OTHER}	/* ',' will protect from matches */
 };
 HttpHeaderFieldInfo *CcFieldsInfo = NULL;
@@ -58,13 +59,13 @@
 /* module initialization */
 
 void
-httpHdrCcInitModule()
+httpHdrCcInitModule(void)
 {
     CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
 }
 
 void
-httpHdrCcCleanModule()
+httpHdrCcCleanModule(void)
 {
     httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
     CcFieldsInfo = NULL;
@@ -73,10 +74,10 @@
 /* implementation */
 
 HttpHdrCc *
-httpHdrCcCreate()
+httpHdrCcCreate(void)
 {
     HttpHdrCc *cc = memAllocate(MEM_HTTP_HDR_CC);
-    cc->max_age = -1;
+    cc->max_age = cc->s_maxage = -1;
     return cc;
 }
 
@@ -132,6 +133,13 @@
 		EBIT_CLR(cc->mask, type);
 	    }
 	    break;
+	case CC_S_MAXAGE:
+	    if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) {
+		debug(65, 2) ("cc: invalid s-maxage specs near '%s'\n", item);
+		cc->s_maxage = -1;
+		EBIT_CLR(cc->mask, type);
+	    }
+	    break;
 	default:
 	    /* note that we ignore most of '=' specs */
 	    break;
@@ -155,6 +163,7 @@
     dup = httpHdrCcCreate();
     dup->mask = cc->mask;
     dup->max_age = cc->max_age;
+    dup->s_maxage = cc->s_maxage;
     return dup;
 }
 
@@ -165,11 +174,18 @@
     int pcount = 0;
     assert(cc && p);
     for (flag = 0; flag < CC_ENUM_END; flag++) {
-	if (flag == CC_MAX_AGE && cc->max_age >= 0) {
-	    packerPrintf(p, "max-age=%d", (int) cc->max_age);
-	    pcount++;
-	} else if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
+	if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
+
+	    /* print option name */
 	    packerPrintf(p, (pcount ? ", %s" : "%s"), strBuf(CcFieldsInfo[flag].name));
+
+	    /* handle options with values */
+	    if (flag == CC_MAX_AGE)
+		packerPrintf(p, "=%d", (int) cc->max_age);
+
+	    if (flag == CC_S_MAXAGE)
+		packerPrintf(p, "=%d", (int) cc->s_maxage);
+
 	    pcount++;
 	}
     }
@@ -181,6 +197,8 @@
     assert(cc && new_cc);
     if (cc->max_age < 0)
 	cc->max_age = new_cc->max_age;
+    if (cc->s_maxage < 0)
+	cc->s_maxage = new_cc->s_maxage;
     cc->mask |= new_cc->mask;
 }
 
@@ -196,6 +214,18 @@
 	EBIT_CLR(cc->mask, CC_MAX_AGE);
 }
 
+/* negative s_maxage will clean old s-maxage setting */
+void
+httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage)
+{
+    assert(cc);
+    cc->s_maxage = s_maxage;
+    if (s_maxage >= 0)
+	EBIT_SET(cc->mask, CC_S_MAXAGE);
+    else
+	EBIT_CLR(cc->mask, CC_S_MAXAGE);
+}
+
 void
 httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
 {
Index: squid/src/HttpHdrContRange.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHdrContRange.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHdrContRange.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHdrContRange.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHdrContRange.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHdrContRange.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 68    HTTP Content-Range Header
  * AUTHOR: Alex Rousskov
@@ -81,7 +81,7 @@
     p++;
     /* do we have last-pos ? */
     if (p - field < flen) {
-	size_t last_pos;
+	ssize_t last_pos;
 	if (!httpHeaderParseSize(p, &last_pos))
 	    return 0;
 	spec->length = size_diff(last_pos + 1, spec->offset);
@@ -110,7 +110,7 @@
  */
 
 HttpHdrContRange *
-httpHdrContRangeCreate()
+httpHdrContRangeCreate(void)
 {
     HttpHdrContRange *r = memAllocate(MEM_HTTP_HDR_CONTENT_RANGE);
     r->spec.offset = r->spec.length = range_spec_unknown;
@@ -187,7 +187,7 @@
 }
 
 void
-httpHdrContRangeSet(HttpHdrContRange * cr, HttpHdrRangeSpec spec, size_t ent_len)
+httpHdrContRangeSet(HttpHdrContRange * cr, HttpHdrRangeSpec spec, ssize_t ent_len)
 {
     assert(cr && ent_len >= 0);
     cr->spec = spec;
Index: squid/src/HttpHdrExtField.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHdrExtField.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHdrExtField.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHdrExtField.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHdrExtField.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHdrExtField.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 69    HTTP Header: Extension Field
  * AUTHOR: Alex Rousskov
Index: squid/src/HttpHdrRange.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHdrRange.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHdrRange.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHdrRange.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHdrRange.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHdrRange.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 64    HTTP Range Header
  * AUTHOR: Alex Rousskov
@@ -55,7 +55,7 @@
 
 
 /* local constants */
-#define range_spec_unknown ((size_t)-1)
+#define range_spec_unknown ((ssize_t)-1)
 
 /* local routines */
 #define known_spec(s) ((s) != range_spec_unknown)
@@ -73,7 +73,7 @@
  */
 
 static HttpHdrRangeSpec *
-httpHdrRangeSpecCreate()
+httpHdrRangeSpecCreate(void)
 {
     return memAllocate(MEM_HTTP_HDR_RANGE_SPEC);
 }
@@ -102,7 +102,7 @@
 	p++;
 	/* do we have last-pos ? */
 	if (p - field < flen) {
-	    size_t last_pos;
+	    ssize_t last_pos;
 	    if (!httpHeaderParseSize(p, &last_pos))
 		return NULL;
 	    spec.length = size_diff(last_pos + 1, spec.offset);
@@ -209,7 +209,7 @@
  */
 
 HttpHdrRange *
-httpHdrRangeCreate()
+httpHdrRangeCreate(void)
 {
     HttpHdrRange *r = memAllocate(MEM_HTTP_HDR_RANGE);
     stackInit(&r->specs);
@@ -303,7 +303,7 @@
  *   - there is at least one range spec
  */
 int
-httpHdrRangeCanonize(HttpHdrRange * range, size_t clen)
+httpHdrRangeCanonize(HttpHdrRange * range, ssize_t clen)
 {
     int i;
     HttpHdrRangeSpec *spec;
@@ -386,8 +386,10 @@
     return 0;
 }
 
-/* hack: returns true if range specs may be too "complex" when "canonized" */
-/* see also: httpHdrRangeIsComplex */
+/*
+ * hack: returns true if range specs may be too "complex" when "canonized".
+ * see also: httpHdrRangeIsComplex.
+ */
 int
 httpHdrRangeWillBeComplex(const HttpHdrRange * range)
 {
@@ -409,12 +411,14 @@
     return 0;
 }
 
-/* Returns lowest known offset in range spec(s), or range_spec_unknown */
-/* this is used for size limiting */
-size_t
+/*
+ * Returns lowest known offset in range spec(s), or range_spec_unknown
+ * this is used for size limiting
+ */
+ssize_t
 httpHdrRangeFirstOffset(const HttpHdrRange * range)
 {
-    size_t offset = range_spec_unknown;
+    ssize_t offset = range_spec_unknown;
     HttpHdrRangePos pos = HttpHdrRangeInitPos;
     const HttpHdrRangeSpec *spec;
     assert(range);
@@ -425,16 +429,17 @@
     return offset;
 }
 
-/* Returns lowest offset in range spec(s), 0 if unknown */
-/* This is used for finding out where we need to start if all
+/*
+ * Returns lowest offset in range spec(s), 0 if unknown.
+ * This is used for finding out where we need to start if all
  * ranges are combined into one, for example FTP REST.
  * Use 0 for size if unknown
  */
-size_t
-httpHdrRangeLowestOffset(const HttpHdrRange * range, size_t size)
+ssize_t
+httpHdrRangeLowestOffset(const HttpHdrRange * range, ssize_t size)
 {
-    size_t offset = range_spec_unknown;
-    size_t current;
+    ssize_t offset = range_spec_unknown;
+    ssize_t current;
     HttpHdrRangePos pos = HttpHdrRangeInitPos;
     const HttpHdrRangeSpec *spec;
     assert(range);
Index: squid/src/HttpHeader.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHeader.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHeader.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHeader.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHeader.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHeader.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 55    HTTP Header
  * AUTHOR: Alex Rousskov
@@ -141,6 +141,7 @@
     HDR_CONNECTION,
     HDR_IF_MATCH, HDR_IF_NONE_MATCH,
     HDR_LINK, HDR_PRAGMA,
+    HDR_PROXY_CONNECTION,
     /* HDR_TRANSFER_ENCODING, */
     HDR_UPGRADE,
     HDR_VARY,
@@ -227,7 +228,7 @@
  */
 
 void
-httpHeaderInitModule()
+httpHeaderInitModule(void)
 {
     int i;
     /* check that we have enough space for masks */
@@ -264,7 +265,7 @@
 }
 
 void
-httpHeaderCleanModule()
+httpHeaderCleanModule(void)
 {
     httpHeaderDestroyFieldsInfo(Headers, HDR_ENUM_END);
     Headers = NULL;
@@ -383,7 +384,16 @@
     HttpHeaderStats[hdr->owner].parsedCount++;
     /* commonn format headers are "<name>:[ws]<value>" lines delimited by <CRLF> */
     while (field_start < header_end) {
-	const char *field_end = field_start + strcspn(field_start, "\r\n");
+	const char *field_end;
+	const char *field_ptr = field_start;
+	do {
+	    field_end = field_ptr = field_ptr + strcspn(field_ptr, "\r\n");
+	    /* skip CRLF */
+	    if (*field_ptr == '\r')
+		field_ptr++;
+	    if (*field_ptr == '\n')
+		field_ptr++;
+	} while (*field_ptr == ' ' || *field_ptr == '\t');
 	if (!*field_end || field_end > header_end)
 	    return httpHeaderReset(hdr);	/* missing <CRLF> */
 	e = httpHeaderEntryParseCreate(field_start, field_end);
Index: squid/src/HttpHeaderTools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpHeaderTools.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpHeaderTools.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpHeaderTools.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHeaderTools.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpHeaderTools.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 66    HTTP Header Tools
  * AUTHOR: Alex Rousskov
@@ -97,17 +97,18 @@
 }
 
 /* same as httpHeaderPutStr, but formats the string using snprintf first */
-#if STDC_HEADERS
 void
+#if STDC_HEADERS
 httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...)
-{
-    va_list args;
-    va_start(args, fmt);
 #else
-void
 httpHeaderPutStrf(va_alist)
      va_dcl
+#endif
 {
+#if STDC_HEADERS
+    va_list args;
+    va_start(args, fmt);
+#else
     va_list args;
     HttpHeader *hdr = NULL;
     http_hdr_type id = HDR_ENUM_END;
@@ -135,7 +136,7 @@
 
 /* wrapper arrounf PutContRange */
 void
-httpHeaderAddContRange(HttpHeader * hdr, HttpHdrRangeSpec spec, size_t ent_len)
+httpHeaderAddContRange(HttpHeader * hdr, HttpHdrRangeSpec spec, ssize_t ent_len)
 {
     HttpHdrContRange *cr = httpHdrContRangeCreate();
     assert(hdr && ent_len >= 0);
@@ -146,23 +147,28 @@
 
 
 /*
- * return true if a given directive is found in at least one of the "connection" header-fields
- * note: if HDR_PROXY_CONNECTION is present we ignore HDR_CONNECTION
+ * return true if a given directive is found in at least one of
+ * the "connection" header-fields note: if HDR_PROXY_CONNECTION is
+ * present we ignore HDR_CONNECTION.
  */
 int
 httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive)
 {
-    if (httpHeaderHas(hdr, HDR_PROXY_CONNECTION)) {
-	const char *str = httpHeaderGetStr(hdr, HDR_PROXY_CONNECTION);
-	return str && !strcasecmp(str, directive);
-    }
-    if (httpHeaderHas(hdr, HDR_CONNECTION)) {
-	String str = httpHeaderGetList(hdr, HDR_CONNECTION);
-	const int res = strListIsMember(&str, directive, ',');
-	stringClean(&str);
-	return res;
-    }
-    return 0;
+    String list;
+    http_hdr_type ht;
+    int res;
+    /* what type of header do we have? */
+    if (httpHeaderHas(hdr, HDR_PROXY_CONNECTION))
+	ht = HDR_PROXY_CONNECTION;
+    else if (httpHeaderHas(hdr, HDR_CONNECTION))
+	ht = HDR_CONNECTION;
+    else
+	return 0;
+
+    list = httpHeaderGetList(hdr, ht);
+    res = strListIsMember(&list, directive, ',');
+    stringClean(&list);
+    return res;
 }
 
 /* returns true iff "m" is a member of the list */
@@ -171,9 +177,12 @@
 {
     const char *pos = NULL;
     const char *item;
+    int ilen = 0;
+    int mlen;
     assert(list && m);
-    while (strListGetItem(list, del, &item, NULL, &pos)) {
-	if (!strcasecmp(item, m))
+    mlen = strlen(m);
+    while (strListGetItem(list, del, &item, &ilen, &pos)) {
+	if (mlen == ilen && !strncasecmp(item, m, ilen))
 	    return 1;
     }
     return 0;
@@ -183,6 +192,18 @@
 int
 strListIsSubstr(const String * list, const char *s, char del)
 {
+    assert(list && del);
+    return strStr(*list, s) != 0;
+
+    /*
+     * Note: the original code with a loop is broken because it uses strstr()
+     * instead of strnstr(). If 's' contains a 'del', strListIsSubstr() may
+     * return true when it should not. If 's' does not contain a 'del', the
+     * implementaion is equavalent to strstr()! Thus, we replace the loop with
+     * strstr() above until strnstr() is available.
+     */
+
+#ifdef BROKEN_CODE
     const char *pos = NULL;
     const char *item;
     assert(list && s);
@@ -191,6 +212,7 @@
 	    return 1;
     }
     return 0;
+#endif
 }
 
 /* appends an item to the list */
@@ -276,7 +298,7 @@
 }
 
 int
-httpHeaderParseSize(const char *start, size_t * value)
+httpHeaderParseSize(const char *start, ssize_t * value)
 {
     int v;
     const int res = httpHeaderParseInt(start, &v);
@@ -366,5 +388,6 @@
 	if (c2)
 	    len2++;
     }
+    /* NOTREACHED */
     return 0;
 }
Index: squid/src/HttpReply.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpReply.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpReply.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpReply.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpReply.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpReply.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 58    HTTP Reply (Response)
  * AUTHOR: Alex Rousskov
@@ -60,7 +60,7 @@
 
 /* module initialization */
 void
-httpReplyInitModule()
+httpReplyInitModule(void)
 {
     httpHeaderMaskInit(&Denied304HeadersMask, 0);
     httpHeaderCalcMask(&Denied304HeadersMask, (const int *) Denied304HeadersArr, countof(Denied304HeadersArr));
@@ -68,7 +68,7 @@
 
 
 HttpReply *
-httpReplyCreate()
+httpReplyCreate(void)
 {
     HttpReply *rep = memAllocate(MEM_HTTP_REPLY);
     debug(58, 7) ("creating rep: %p\n", rep);
@@ -125,21 +125,31 @@
     httpReplyDoDestroy(new_rep);
 }
 
-/* parses a 4K buffer that may not be 0-terminated; returns true on success */
+/*
+ * httpReplyParse takes character buffer of HTTP headers (buf),
+ * which may not be NULL-terminated, and fills in an HttpReply
+ * structure (rep).  The parameter 'end' specifies the offset to
+ * the end of the reply headers.  The caller may know where the
+ * end is, but is unable to NULL-terminate the buffer.  This function
+ * returns true on success.
+ */
 int
-httpReplyParse(HttpReply * rep, const char *buf)
+httpReplyParse(HttpReply * rep, const char *buf, ssize_t end)
 {
     /*
-     * this extra buffer/copy will be eliminated when headers become meta-data
-     * in store. Currently we have to xstrncpy the buffer becuase store.c may
-     * feed a non 0-terminated buffer to us.
+     * this extra buffer/copy will be eliminated when headers become
+     * meta-data in store. Currently we have to xstrncpy the buffer
+     * becuase somebody may feed a non NULL-terminated buffer to
+     * us.
      */
     char *headers = memAllocate(MEM_4K_BUF);
     int success;
     /* reset current state, because we are not used in incremental fashion */
     httpReplyReset(rep);
-    /* put a 0-terminator */
+    /* put a string terminator */
     xstrncpy(headers, buf, 4096);
+    if (end >= 0 && end < 4096)
+	*(headers + end) = '\0';
     success = httpReplyParseStep(rep, headers, 0);
     memFree(headers, MEM_4K_BUF);
     return success == 1;
@@ -301,8 +311,10 @@
     rep->content_range = httpHeaderGetContRange(hdr);
     rep->keep_alive = httpMsgIsPersistent(rep->sline.version, &rep->header);
     /* final adjustments */
-    /* The max-age directive takes priority over Expires, check it first */
-    if (rep->cache_control && rep->cache_control->max_age >= 0)
+    /* The s-maxage and max-age directive takes priority over Expires */
+    if (rep->cache_control && rep->cache_control->s_maxage >= 0)
+	rep->expires = squid_curtime + rep->cache_control->s_maxage;
+    else if (rep->cache_control && rep->cache_control->max_age >= 0)
 	rep->expires = squid_curtime + rep->cache_control->max_age;
     else
 	/*
@@ -401,3 +413,22 @@
     *parse_start = *blk_end;
     return 1;
 }
+
+/*
+ * Returns the body size of a HTTP response
+ */
+int
+httpReplyBodySize(method_t method, HttpReply * reply)
+{
+    if (METHOD_HEAD == method)
+	return 0;
+    else if (reply->sline.status == HTTP_OK)
+	(void) 0;		/* common case, continue */
+    else if (reply->sline.status == HTTP_NO_CONTENT)
+	return 0;
+    else if (reply->sline.status == HTTP_NOT_MODIFIED)
+	return 0;
+    else if (reply->sline.status < HTTP_OK)
+	return 0;
+    return reply->content_length;
+}
Index: squid/src/HttpRequest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpRequest.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpRequest.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpRequest.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpRequest.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpRequest.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 73    HTTP Request
  * AUTHOR: Duane Wessels
@@ -44,6 +44,9 @@
     if (urlpath)
 	stringReset(&req->urlpath, urlpath);
     req->max_forwards = -1;
+    req->lastmod = -1;
+    req->client_addr = no_addr;
+    req->my_addr = no_addr;
     httpHeaderInit(&req->header, hoRequest);
     return req;
 }
@@ -151,3 +154,13 @@
 	return 0;
     return 1;
 }
+
+/* returns true if header is allowed to be passed on */
+int
+httpRequestHdrAllowedByName(http_hdr_type id)
+{
+    /* check with anonymizer tables */
+    if (CBIT_TEST(Config.anonymize_headers, id))
+	return 0;
+    return 1;
+}
Index: squid/src/HttpStatusLine.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/HttpStatusLine.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/HttpStatusLine.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/HttpStatusLine.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpStatusLine.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: HttpStatusLine.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 57    HTTP Status-line
  * AUTHOR: Alex Rousskov
Index: squid/src/Makefile.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/Makefile.in,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/Makefile.in	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/Makefile.in	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+#  $Id: Makefile.in,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -97,6 +97,7 @@
 		@DELAY_OBJS@ \
 		disk.o \
 		dns.o \
+		dns_internal.o \
 		errorpage.o \
 		ETag.o \
 		event.o \
@@ -151,10 +152,12 @@
 		String.o \
 		stmem.o \
 		store.o \
-		store_clean.o \
+		store_io.o \
+		store_io_ufs.o \
 		store_client.o \
 		store_digest.o \
 		store_dir.o \
+		store_dir_ufs.o \
 		store_key_md5.o \
 		store_log.o \
 		store_rebuild.o \
@@ -168,6 +171,7 @@
 		urn.o \
 		useragent.o \
 		wais.o \
+		wccp.o \
 		whois.o \
 		$(XTRA_OBJS)
 
@@ -181,7 +185,8 @@
 
 ASYNC_OBJS	= \
 		aiops.o \
-		async_io.o
+		async_io.o \
+		store_io_asyncufs.o
 
 LEAKFINDER_OBJS	= \
 		leakfinder.o
@@ -361,6 +366,7 @@
 
 distclean:	clean
 	-rm -f Makefile squid.conf squid.conf.pre
+	-rm -f Makefile.bak
 
 tags:
 	ctags *.[ch] ../include/*.h ../lib/*.[ch]
Index: squid/src/MemPool.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/MemPool.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/MemPool.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/MemPool.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: MemPool.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: MemPool.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 63    Low Level Memory Pool Management
  * AUTHOR: Alex Rousskov
@@ -55,9 +55,9 @@
 static Stack Pools;
 
 /* local prototypes */
-static void memShrink(size_t new_limit);
+static void memShrink(ssize_t new_limit);
 static void memPoolDescribe(const MemPool * pool);
-static void memPoolShrink(MemPool * pool, size_t new_limit);
+static void memPoolShrink(MemPool * pool, ssize_t new_limit);
 
 
 
@@ -132,9 +132,9 @@
 
 
 static void
-memShrink(size_t new_limit)
+memShrink(ssize_t new_limit)
 {
-    size_t start_limit = TheMeter.idle.level;
+    ssize_t start_limit = TheMeter.idle.level;
     int i;
     assert(start_limit >= 0 && new_limit >= 0);
     debug(63, 1) ("memShrink: started with %d KB goal: %d KB\n",
@@ -142,7 +142,7 @@
     /* first phase: cut proportionally to the pool idle size */
     for (i = 0; i < Pools.count && TheMeter.idle.level > new_limit; ++i) {
 	MemPool *pool = Pools.items[i];
-	const size_t target_pool_size = (size_t) ((double) pool->meter.idle.level * new_limit) / start_limit;
+	const ssize_t target_pool_size = (size_t) ((double) pool->meter.idle.level * new_limit) / start_limit;
 	memPoolShrink(pool, target_pool_size);
     }
     debug(63, 1) ("memShrink: 1st phase done with %d KB left\n", toKB(TheMeter.idle.level));
@@ -266,7 +266,7 @@
 }
 
 static void
-memPoolShrink(MemPool * pool, size_t new_limit)
+memPoolShrink(MemPool * pool, ssize_t new_limit)
 {
     assert(pool);
     assert(new_limit >= 0);
Index: squid/src/access_log.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/access_log.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/access_log.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/access_log.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: access_log.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: access_log.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 46    Access Log
  * AUTHOR: Duane Wessels
@@ -135,28 +135,44 @@
      * more readable.
      */
     while ((c = *(const unsigned char *) header++) != '\0') {
-	if (c <= 0x1F
-	    || c >= 0x7F
-	    || c == '"'
-	    || c == '#'
-	    || c == '%'
-	    || c == ';'
-	    || c == '<'
-	    || c == '>'
-	    || c == '?'
-	    || c == '{'
-	    || c == '}'
-	    || c == '|'
-	    || c == '\\'
-	    || c == '^'
-	    || c == '~'
-	    || c == '`'
-	    || c == '['
+#if !OLD_LOG_MIME
+	if (c == '\r') {
+	    *buf_cursor++ = '\\';
+	    *buf_cursor++ = 'r';
+	} else if (c == '\n') {
+	    *buf_cursor++ = '\\';
+	    *buf_cursor++ = 'n';
+	} else
+#endif
+	    if (c <= 0x1F
+		|| c >= 0x7F
+#if OLD_LOG_MIME
+		|| c == '"'
+		|| c == '#'
+		|| c == '%'
+		|| c == ';'
+		|| c == '<'
+		|| c == '>'
+		|| c == '?'
+		|| c == '{'
+		|| c == '}'
+		|| c == '|'
+		|| c == '\\'
+		|| c == '^'
+		|| c == '~'
+		|| c == '`'
+#endif
+		|| c == '['
 	    || c == ']') {
 	    *buf_cursor++ = '%';
 	    i = c * 2;
 	    *buf_cursor++ = c2x[i];
 	    *buf_cursor++ = c2x[i + 1];
+#if !OLD_LOG_MIME
+	} else if (c == '\\') {
+	    *buf_cursor++ = '\\';
+	    *buf_cursor++ = '\\';
+#endif
 	} else {
 	    *buf_cursor++ = (char) c;
 	}
@@ -216,10 +232,23 @@
 {
     assert(fname);
     xstrncpy(LogfileName, fname, SQUID_MAXPATHLEN);
-    LogfileFD = file_open(LogfileName, O_WRONLY | O_CREAT, NULL, NULL, NULL);
+    LogfileFD = file_open(LogfileName, O_WRONLY | O_CREAT);
     if (LogfileFD == DISK_ERROR) {
-	debug(50, 0) ("%s: %s\n", LogfileName, xstrerror());
-	fatalf("Cannot open %s: %s", LogfileName, xstrerror());
+	if (ENOENT == errno) {
+	    fatalf("%s cannot be created, since the\n"
+		"\tdirectory it is to reside in does not exist."
+		"\t(%s)\n", LogfileName, xstrerror());
+	} else if (EACCES == errno) {
+	    fatalf("cannot create %s:\n"
+		"\t%s.\n"
+		"\tThe directory access.log is to reside in needs to be\n"
+		"\twriteable by the user %s, the cache_effective_user\n"
+		"\tset in squid.conf.",
+		LogfileName, xstrerror(), Config.effectiveUser);
+	} else {
+	    debug(50, 0) ("%s: %s\n", LogfileName, xstrerror());
+	    fatalf("Cannot open %s: %s", LogfileName, xstrerror());
+	}
     }
     LogfileStatus = LOG_ENABLE;
 }
@@ -314,16 +343,16 @@
 	i--;
 	snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-	rename(from, to);
+	xrename(from, to);
     }
     /* Rotate the current log to .0 */
     file_close(LogfileFD);	/* always close */
     if (Config.Log.rotateNumber > 0) {
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-	rename(fname, to);
+	xrename(fname, to);
     }
     /* Reopen the log.  It may have been renamed "manually" */
-    LogfileFD = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL);
+    LogfileFD = file_open(fname, O_WRONLY | O_CREAT);
     if (LogfileFD == DISK_ERROR) {
 	debug(46, 0) ("accessLogRotate: Cannot open logfile: %s\n", fname);
 	LogfileStatus = LOG_DISABLE;
@@ -371,7 +400,7 @@
 	    fatal("Cannot open Multicast Miss Stream Socket");
 	debug(46, 1) ("Multicast Miss Stream Socket opened on FD %d\n",
 	    mcast_miss_fd);
-	mcastSetTtl(mcast_miss_fd, 128);
+	mcastSetTtl(mcast_miss_fd, Config.mcast_miss.ttl);
 	if (strlen(Config.mcast_miss.encode_key) < 16)
 	    fatal("mcast_encode_key is too short, must be 16 characters");
     }
Index: squid/src/acl.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/acl.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/acl.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/acl.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: acl.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -175,6 +175,10 @@
 	return ACL_URL_REGEX;
     if (!strcmp(s, "port"))
 	return ACL_URL_PORT;
+    if (!strcmp(s, "myport"))
+	return ACL_MY_PORT;
+    if (!strcmp(s, "maxconn"))
+	return ACL_MAXCONN;
 #if USE_IDENT
     if (!strcmp(s, "ident"))
 	return ACL_IDENT;
@@ -229,6 +233,10 @@
 	return "url_regex";
     if (type == ACL_URL_PORT)
 	return "port";
+    if (type == ACL_MY_PORT)
+	return "myport";
+    if (type == ACL_MAXCONN)
+	return "maxconn";
 #if USE_IDENT
     if (type == ACL_IDENT)
 	return "ident";
@@ -699,11 +707,13 @@
 	aclParseRegexList(&A->data);
 	break;
     case ACL_SRC_ASN:
+    case ACL_MAXCONN:
     case ACL_DST_ASN:
     case ACL_NETDB_SRC_RTT:
 	aclParseIntlist(&A->data);
 	break;
     case ACL_URL_PORT:
+    case ACL_MY_PORT:
 	aclParseIntRange(&A->data);
 	break;
 #if USE_IDENT
@@ -993,20 +1003,27 @@
 {
     char *sent_auth;
     char *cleartext;
-
     if (proxy_auth == NULL)
 	return 0;
-    if (strlen(proxy_auth) < SKIP_BASIC_SZ)
+    debug(28, 6) ("aclDecodeProxyAuth: header = '%s'\n", proxy_auth);
+    if (strncasecmp(proxy_auth, "Basic ", 6) != 0) {
+	debug(28, 1) ("aclDecodeProxyAuth: Unsupported proxy-auth sheme, '%s'\n", proxy_auth);
 	return 0;
-    proxy_auth += SKIP_BASIC_SZ;
-    sent_auth = xstrdup(proxy_auth);	/* username and password */
-    /* Trim trailing \n before decoding */
-    strtok(sent_auth, "\n");
+    }
+    proxy_auth += 6;		/* "Basic " */
     /* Trim leading whitespace before decoding */
     while (xisspace(*proxy_auth))
 	proxy_auth++;
+    sent_auth = xstrdup(proxy_auth);	/* username and password */
+    /* Trim trailing \n before decoding */
+    strtok(sent_auth, "\n");
     cleartext = uudecode(sent_auth);
     xfree(sent_auth);
+    /*
+     * Don't allow NL or CR in the credentials.
+     * Oezguer Kesim <oec@codeblau.de>
+     */
+    strtok(cleartext, "\r\n");
     debug(28, 6) ("aclDecodeProxyAuth: cleartext = '%s'\n", cleartext);
     xstrncpy(buf, cleartext, bufsize);
     xfree(cleartext);
@@ -1014,7 +1031,12 @@
     if ((*password = strchr(*user, ':')) != NULL)
 	*(*password)++ = '\0';
     if (*password == NULL) {
-	debug(28, 1) ("aclDecodeProxyAuth: no password in proxy authorization header\n");
+	debug(28, 1) ("aclDecodeProxyAuth: no password in proxy authorization header '%s'\n", proxy_auth);
+	return 0;
+    }
+    if (**password == '\0') {
+	debug(28, 1) ("aclDecodeProxyAuth: Disallowing empty password,"
+	    "user is '%s'\n", *user);
 	return 0;
     }
     return 1;
@@ -1042,7 +1064,8 @@
     debug(28, 5) ("aclMatchProxyAuth: checking user '%s'\n", user);
 
     if (auth_user) {
-	/* This should be optimized to a boolean argument indicating that the
+	/*
+	 * This should be optimized to a boolean argument indicating that the
 	 * password is invalid, instead of passing full acl_proxy_auth_user
 	 * structures, and all messing with checklist->proxy_auth should
 	 * be restricted the functions that deal with the authenticator.
@@ -1056,8 +1079,11 @@
 	    debug(28, 4) ("aclMatchProxyAuth: authentication failed for user '%s'\n",
 		user);
 	    aclFreeProxyAuthUser(auth_user);
-	    /* copy username to request for logging on client-side unless ident
-	     * is known (do not override ident with false proxy auth names) */
+	    /*
+	     * copy username to request for logging on client-side
+	     * unless ident is known (do not override ident with
+	     * false proxy auth names)
+	     */
 	    if (!*checklist->request->user_ident)
 		xstrncpy(checklist->request->user_ident, user, USER_IDENT_SZ);
 	    return -2;
@@ -1067,6 +1093,8 @@
 	    /* store validated user in hash, after filling in expiretime */
 	    xstrncpy(checklist->request->user_ident, user, USER_IDENT_SZ);
 	    auth_user->expiretime = current_time.tv_sec + Config.authenticateTTL;
+	    auth_user->ip_expiretime = squid_curtime + Config.authenticateIpTTL;
+	    auth_user->ipaddr = checklist->src_addr;
 	    hash_join(proxy_auth_cache, (hash_link *) auth_user);
 	    /* Continue checking below, as normal */
 	}
@@ -1080,12 +1108,26 @@
 	return -1;
     } else if ((0 == strcmp(auth_user->passwd, password)) &&
 	(auth_user->expiretime > current_time.tv_sec)) {
-	/* user already known and valid */
-	debug(28, 5) ("aclMatchProxyAuth: user '%s' previously validated\n",
-	    user);
-	/* copy username to request for logging on client-side */
-	xstrncpy(checklist->request->user_ident, user, USER_IDENT_SZ);
-	return aclMatchUser(data, user);
+	if (checklist->src_addr.s_addr == auth_user->ipaddr.s_addr
+	    || auth_user->ip_expiretime <= squid_curtime) {
+	    /* user already known and valid */
+	    debug(28, 5) ("aclMatchProxyAuth: user '%s' previously validated\n",
+		user);
+	    /* Update IP ttl */
+	    auth_user->ip_expiretime = squid_curtime + Config.authenticateIpTTL;
+	    auth_user->ipaddr = checklist->src_addr;
+	    /* copy username to request for logging on client-side */
+	    xstrncpy(checklist->request->user_ident, user, USER_IDENT_SZ);
+	    return aclMatchUser(data, user);
+	} else {
+	    /* user has switched to another IP addr */
+	    debug(28, 1) ("aclMatchProxyAuth: user '%s' has changed IP address\n", user);
+	    /* remove this user from the hash, making him unknown */
+	    hash_remove_link(proxy_auth_cache, (hash_link *) auth_user);
+	    aclFreeProxyAuthUser(auth_user);
+	    /* require the user to reauthenticate */
+	    return -2;
+	}
     } else {
 	/* password mismatch/timeout */
 	debug(28, 4) ("aclMatchProxyAuth: user '%s' password mismatch/timeout\n",
@@ -1232,6 +1274,7 @@
     const char *fqdn = NULL;
     char *esc_buf;
     const char *header;
+    const char *browser;
     int k;
     if (!ae)
 	return 0;
@@ -1329,8 +1372,15 @@
 	safe_free(esc_buf);
 	return k;
 	/* NOTREACHED */
+    case ACL_MAXCONN:
+	k = clientdbEstablished(checklist->src_addr, 0);
+	return ((k > ((intlist *) ae->data)->i) ? 0 : 1);
+	/* NOTREACHED */
     case ACL_URL_PORT:
-	return aclMatchIntegerRange(ae->data, r->port);
+	return aclMatchIntegerRange(ae->data, (int) r->port);
+	/* NOTREACHED */
+    case ACL_MY_PORT:
+	return aclMatchIntegerRange(ae->data, (int) checklist->my_port);
 	/* NOTREACHED */
 #if USE_IDENT
     case ACL_IDENT:
@@ -1349,7 +1399,10 @@
 	return aclMatchInteger(ae->data, r->method);
 	/* NOTREACHED */
     case ACL_BROWSER:
-	return aclMatchRegex(ae->data, checklist->browser);
+	browser = httpHeaderGetStr(&checklist->request->header, HDR_USER_AGENT);
+	if (NULL == browser)
+	    return 0;
+	return aclMatchRegex(ae->data, browser);
 	/* NOTREACHED */
     case ACL_PROXY_AUTH:
 	if (NULL == r) {
@@ -1675,9 +1728,6 @@
 aclCheck_t *
 aclChecklistCreate(const acl_access * A,
     request_t * request,
-    struct in_addr src_addr,
-    struct in_addr my_addr,
-    const char *user_agent,
     const char *ident)
 {
     int i;
@@ -1689,14 +1739,14 @@
      * pointer, so lock it.
      */
     cbdataLock(A);
-    if (request != NULL)
+    if (request != NULL) {
 	checklist->request = requestLink(request);
-    checklist->src_addr = src_addr;
-    checklist->my_addr = my_addr;
+	checklist->src_addr = request->client_addr;
+	checklist->my_addr = request->my_addr;
+	checklist->my_port = request->my_port;
+    }
     for (i = 0; i < ACL_ENUM_MAX; i++)
 	checklist->state[i] = ACL_LOOKUP_NONE;
-    if (user_agent)
-	xstrncpy(checklist->browser, user_agent, BROWSERNAMELEN);
 #if USE_IDENT
     if (ident)
 	xstrncpy(checklist->ident, ident, USER_IDENT_SZ);
@@ -1804,9 +1854,11 @@
 	case ACL_SRC_ASN:
 	case ACL_DST_ASN:
 	case ACL_NETDB_SRC_RTT:
+	case ACL_MAXCONN:
 	    intlistDestroy((intlist **) & a->data);
 	    break;
 	case ACL_URL_PORT:
+	case ACL_MY_PORT:
 	    aclDestroyIntRange(a->data);
 	    break;
 	case ACL_NONE:
@@ -1886,10 +1938,10 @@
 /* compare two domains */
 
 static int
-aclDomainCompare(const void *data, splayNode * n)
+aclDomainCompare(const void *a, const void *b)
 {
-    const char *d1 = data;
-    const char *d2 = n->data;
+    const char *d1 = a;
+    const char *d2 = b;
     int l1;
     int l2;
     while ('.' == *d1)
@@ -1924,29 +1976,11 @@
 /* compare a host and a domain */
 
 static int
-aclHostDomainCompare(const void *data, splayNode * n)
+aclHostDomainCompare(const void *a, const void *b)
 {
-    const char *h = data;
-    char *d = n->data;
-    int l1;
-    int l2;
-    if (matchDomainName(d, h))
-	return 0;
-    l1 = strlen(h);
-    l2 = strlen(d);
-    /* h != d */
-    while (xtolower(h[--l1]) == xtolower(d[--l2])) {
-	if (l1 == 0)
-	    break;
-	if (l2 == 0)
-	    break;
-    }
-    /* a '.' is a special case */
-    if ((h[l1] == '.') && (l1 == 0))
-	return -1;		/* domain(h) < d */
-    if ((d[l2] == '.') && (l2 == 0))
-	return 1;		/* domain(h) > d */
-    return (xtolower(h[l1]) - xtolower(d[l2]));
+    const char *h = a;
+    const char *d = b;
+    return matchDomainName(h, d);
 }
 
 /* compare two network specs
@@ -1963,12 +1997,12 @@
 /* compare an address and a network spec */
 
 static int
-aclIpNetworkCompare(const void *a, splayNode * n)
+aclIpNetworkCompare(const void *a, const void *b)
 {
-    struct in_addr A = *(struct in_addr *) a;
-    acl_ip_data *q = n->data;
-    struct in_addr B = q->addr1;
-    struct in_addr C = q->addr2;
+    struct in_addr A = *(const struct in_addr *) a;
+    const acl_ip_data *q = b;
+    const struct in_addr B = q->addr1;
+    const struct in_addr C = q->addr2;
     int rc = 0;
     A.s_addr &= q->mask.s_addr;	/* apply netmask */
     if (C.s_addr == 0) {	/* single address check */
@@ -2148,10 +2182,12 @@
 	return aclDumpRegexList(a->data);
 	break;
     case ACL_SRC_ASN:
+    case ACL_MAXCONN:
     case ACL_DST_ASN:
 	return aclDumpIntlistList(a->data);
 	break;
     case ACL_URL_PORT:
+    case ACL_MY_PORT:
 	return aclDumpIntRangeList(a->data);
 	break;
     case ACL_PROTO:
@@ -2281,34 +2317,129 @@
 {
     struct arpreq arpReq;
     struct sockaddr_in ipAddr;
+    unsigned char ifbuffer[sizeof(struct ifreq) * 64];
+    struct ifconf ifc;
+    struct ifreq *ifr;
+    int offset;
     splayNode **Top = dataptr;
+    /*
+     * The linux kernel 2.2 maintains per interface ARP caches and
+     * thus requires an interface name when doing ARP queries.
+     * 
+     * The older 2.0 kernels appear to use a unified ARP cache,
+     * and require an empty interface name
+     * 
+     * To support both, we attempt the lookup with a blank interface
+     * name first. If that does not succeed, the try each interface
+     * in turn
+     */
+    /*
+     * Set up structures for ARP lookup with blank interface name
+     */
     ipAddr.sin_family = AF_INET;
     ipAddr.sin_port = 0;
     ipAddr.sin_addr = c;
+    memset(&arpReq, '\0', sizeof(arpReq));
     memcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
-    arpReq.arp_dev[0] = '\0';
-    arpReq.arp_flags = 0;
-    /* any AF_INET socket will do... gives back hardware type, device, etc */
-    if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) == -1) {
-	debug(28, 1) ("ARP query failed - %d", errno);
+    /* Query ARP table */
+    if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) {
+	/* Skip non-ethernet interfaces */
+	if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {
+	    return 0;
+	}
+	debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n",
+	    arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff,
+	    arpReq.arp_ha.sa_data[2] & 0xff, arpReq.arp_ha.sa_data[3] & 0xff,
+	    arpReq.arp_ha.sa_data[4] & 0xff, arpReq.arp_ha.sa_data[5] & 0xff);
+	/* Do lookup */
+	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
+	debug(28, 3) ("aclMatchArp: '%s' %s\n",
+	    inet_ntoa(c), splayLastResult ? "NOT found" : "found");
+	return (0 == splayLastResult);
+    }
+    /* lookup list of interface names */
+    ifc.ifc_len = sizeof(ifbuffer);
+    ifc.ifc_buf = ifbuffer;
+    if (ioctl(HttpSockets[0], SIOCGIFCONF, &ifc) < 0) {
+	debug(28, 1) ("Attempt to retrieve interface list failed: %s\n",
+	    xstrerror());
 	return 0;
-    } else if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {
-	debug(28, 1) ("Non-ethernet interface returned from ARP query - %d",
-	    arpReq.arp_ha.sa_family);
-	/* update here and MAC address parsing to handle non-ethernet */
+    }
+    if (ifc.ifc_len > sizeof(ifbuffer)) {
+	debug(28, 1) ("Interface list too long - %d\n", ifc.ifc_len);
 	return 0;
-    } else
+    }
+    /* Attempt ARP lookup on each interface */
+    offset = 0;
+    while (offset < ifc.ifc_len) {
+	ifr = (struct ifreq *) (ifbuffer + offset);
+	offset += sizeof(*ifr);
+	/* Skip loopback and aliased interfaces */
+	if (0 == strncmp(ifr->ifr_name, "lo", 2))
+	    continue;
+	if (NULL != strchr(ifr->ifr_name, ':'))
+	    continue;
+	debug(28, 4) ("Looking up ARP address for %s on %s\n", inet_ntoa(c),
+	    ifr->ifr_name);
+	/* Set up structures for ARP lookup */
+	ipAddr.sin_family = AF_INET;
+	ipAddr.sin_port = 0;
+	ipAddr.sin_addr = c;
+	memset(&arpReq, '\0', sizeof(arpReq));
+	memcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+	strncpy(arpReq.arp_dev, ifr->ifr_name, sizeof(arpReq.arp_dev) - 1);
+	arpReq.arp_dev[sizeof(arpReq.arp_dev) - 1] = '\0';
+	/* Query ARP table */
+	if (-1 == ioctl(HttpSockets[0], SIOCGARP, &arpReq)) {
+	    /*
+	     * Query failed.  Do not log failed lookups or "device
+	     * not supported"
+	     */
+	    if (ENXIO == errno)
+		(void) 0;
+	    else if (ENODEV == errno)
+		(void) 0;
+	    else
+		debug(28, 1) ("ARP query failed: %s: %s\n",
+		    ifr->ifr_name, xstrerror());
+	    continue;
+	}
+	/* Skip non-ethernet interfaces */
+	if (arpReq.arp_ha.sa_family != ARPHRD_ETHER)
+	    continue;
+	debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x on %s\n",
+	    arpReq.arp_ha.sa_data[0] & 0xff,
+	    arpReq.arp_ha.sa_data[1] & 0xff,
+	    arpReq.arp_ha.sa_data[2] & 0xff,
+	    arpReq.arp_ha.sa_data[3] & 0xff,
+	    arpReq.arp_ha.sa_data[4] & 0xff,
+	    arpReq.arp_ha.sa_data[5] & 0xff,
+	    ifr->ifr_name);
+	/* Do lookup */
 	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);
-    debug(28, 3) ("aclMatchArp: '%s' %s\n",
-	inet_ntoa(c), splayLastResult ? "NOT found" : "found");
-    return !splayLastResult;
+	/* Return if match, otherwise continue to other interfaces */
+	if (0 == splayLastResult) {
+	    debug(28, 3) ("aclMatchArp: %s found on %s\n",
+		inet_ntoa(c), ifr->ifr_name);
+	    return 1;
+	}
+	/*
+	 * Should we stop looking here? Can the same IP address
+	 * exist on multiple interfaces?
+	 */
+    }
+    /*
+     * Address was not found on any interface
+     */
+    debug(28, 3) ("aclMatchArp: %s NOT found\n", inet_ntoa(c));
+    return 0;
 }
 
 static int
-aclArpCompare(const void *data, splayNode * n)
+aclArpCompare(const void *a, const void *b)
 {
-    const unsigned short *d1 = data;
-    const unsigned short *d2 = n->data;
+    const unsigned short *d1 = a;
+    const unsigned short *d2 = b;
     if (d1[0] != d2[0])
 	return (d1[0] > d2[0]) ? 1 : -1;
     if (d1[1] != d2[1])
@@ -2387,7 +2518,7 @@
     static char buf[24];
     while (*W != NULL)
 	W = &(*W)->next;
-    snprintf(buf, sizeof(buf), "%02x:%02x:02x:02x:02x:02x",
+    snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
 	arp->eth[0], arp->eth[1], arp->eth[2], arp->eth[3],
 	arp->eth[4], arp->eth[5]);
     wordlistAdd(state, buf);
Index: squid/src/aiops.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/aiops.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/aiops.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/aiops.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: aiops.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: aiops.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 43    AIOPS
  * AUTHOR: Stewart Forster <slf@connect.com.au>
@@ -46,11 +46,15 @@
 #include	<sched.h>
 #endif
 
-#ifndef NUMTHREADS
-#define	NUMTHREADS		16
-#endif
 #define RIDICULOUS_LENGTH	4096
 
+#if defined(_SQUID_LINUX_)
+/* Linux requires proper use of mutexes or it will segfault deep in the
+ * thread libraries. Observed on Alpha SMP Linux 2.2.10-ac12.
+ */
+#define USE_PROPER_MUTEX 1
+#endif
+
 enum _aio_thread_status {
     _THREAD_STARTING = 0,
     _THREAD_WAITING,
@@ -110,6 +114,7 @@
 int aio_unlink(const char *, aio_result_t *);
 int aio_opendir(const char *, aio_result_t *);
 aio_result_t *aio_poll_done();
+int aio_sync(void);
 
 static void aio_init(void);
 static void aio_queue_request(aio_request_t *);
@@ -183,7 +188,7 @@
 	}
 	threadp->req = NULL;
 	threadp->processed_req = NULL;
-	if (pthread_create(&(threadp->thread), &globattr, aio_thread_loop, threadp)) {
+	if (pthread_create(&threadp->thread, &globattr, aio_thread_loop, threadp)) {
 	    fprintf(stderr, "Thread creation failed\n");
 	    threadp->status = _THREAD_FAILED;
 	    continue;
@@ -205,15 +210,18 @@
 static void *
 aio_thread_loop(void *ptr)
 {
-    aio_thread_t *threadp = (aio_thread_t *) ptr;
+    aio_thread_t *threadp = ptr;
     aio_request_t *request;
     sigset_t new;
 #if !AIO_PROPER_MUTEX
     struct timespec wait_time;
 #endif
 
-    /* Make sure to ignore signals which may possibly get sent to the parent */
-    /* squid thread.  Causes havoc with mutex's and condition waits otherwise */
+    /*
+     * Make sure to ignore signals which may possibly get sent to
+     * the parent squid thread.  Causes havoc with mutex's and
+     * condition waits otherwise
+     */
 
     sigemptyset(&new);
     sigaddset(&new, SIGPIPE);
@@ -236,7 +244,7 @@
 #if AIO_PROPER_MUTEX
 	while (threadp->req == NULL) {
 	    threadp->status = _THREAD_WAITING;
-	    pthread_cond_wait(&(threadp->cond), &(threadp->mutex));
+	    pthread_cond_wait(&threadp->cond, &threadp->mutex);
 	}
 #else
 	/* The timeout is used to unlock the race condition where
@@ -249,8 +257,7 @@
 	wait_time.tv_nsec = 0;
 	while (threadp->req == NULL) {
 	    threadp->status = _THREAD_WAITING;
-	    pthread_cond_timedwait(&(threadp->cond), &(threadp->mutex),
-		&wait_time);
+	    pthread_cond_timedwait(&threadp->cond, &threadp->mutex, &wait_time);
 	    wait_time.tv_sec += 3;	/* then wait 3 seconds between each check */
 	}
 #endif
@@ -292,6 +299,7 @@
 	}
 	threadp->req = NULL;	/* tells main thread that we are done */
     }				/* while */
+    return NULL;
 }				/* aio_thread_loop */
 
 static void
@@ -344,8 +352,8 @@
 	if (request_queue_len < queue_low)
 	    queue_low = request_queue_len;
 	if (squid_curtime >= (last_warn + 15) &&
-	    squid_curtime >= (high_start + 1)) {
-	    debug(43, 1) ("aio_queue_request: WARNING - Running out of I/O theads\n");
+	    squid_curtime >= (high_start + 3)) {
+	    debug(43, 1) ("aio_queue_request: WARNING - Running out of I/O threads\n");
 	    debug(43, 2) ("aio_queue_request: Queue Length: current=%d, high=%d, low=%d, duration=%d\n",
 		request_queue_len, queue_high, queue_low, squid_curtime - high_start);
 	    debug(43, 1) ("aio_queue_request: Perhaps you should increase NUMTHREADS\n");
@@ -386,14 +394,15 @@
     }
     if (request_queue_len > RIDICULOUS_LENGTH) {
 	debug(43, 0) ("aio_queue_request: Async request queue growing uncontrollably!\n");
-	debug(43, 0) ("aio_queue_request: Possible infinite loop somewhere in squid. Restarting...\n");
-	abort();
+	debug(43, 0) ("aio_queue_request: Syncing pending I/O operations.. (blocking)\n");
+	aio_sync();
+	debug(43, 0) ("aio_queue_request: Synced\n");
     }
 }				/* aio_queue_request */
 
 
 static void
-aio_process_request_queue()
+aio_process_request_queue(void)
 {
     aio_thread_t *threadp;
     aio_request_t *requestp;
@@ -766,8 +775,8 @@
 	prev = NULL;
 	threadp = busy_threads_head;
 	while (threadp) {
-	    debug(43, 5) ("%d: %d -> %d\n",
-		threadp->thread,
+	    debug(43, 9) ("aio_poll_threads: %p: request type %d -> status %d\n",
+		threadp,
 		threadp->processed_req->request_type,
 		threadp->status);
 #if AIO_PROPER_MUTEX
@@ -809,7 +818,7 @@
 }				/* aio_poll_threads */
 
 aio_result_t *
-aio_poll_done()
+aio_poll_done(void)
 {
     aio_request_t *requestp;
     aio_result_t *resultp;
@@ -838,13 +847,40 @@
 int
 aio_operations_pending(void)
 {
-    if (request_done_head)
-	return 1;
-    if (busy_threads_head)
+    return request_queue_len + (request_done_head != NULL) + (busy_threads_head != NULL);
+}
+
+int
+aio_overloaded(void)
+{
+    static time_t last_warn = 0;
+    if (aio_operations_pending() > RIDICULOUS_LENGTH / 4) {
+	if (squid_curtime >= (last_warn + 15)) {
+	    debug(43, 0) ("Warning: Async-IO overloaded\n");
+	    last_warn = squid_curtime;
+	}
 	return 1;
+    }
     return 0;
 }
 
+int
+aio_sync(void)
+{
+    int loop_count = 0;
+    do {
+	aio_poll_threads();
+	assert(++loop_count < 10);
+    } while (request_queue_len > 0);
+    return aio_operations_pending();
+}
+
+int
+aio_get_queue_len(void)
+{
+    return request_queue_len;
+}
+
 static void
 aio_debug(aio_request_t * requestp)
 {
Index: squid/src/asn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/asn.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/asn.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/asn.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: asn.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: asn.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 53    AS Number handling
  * AUTHOR: Duane Wessels, Kostas Anagnostakis
@@ -196,7 +196,7 @@
     if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) {
 	e = storeCreateEntry(asres, asres, null_request_flags, METHOD_GET);
 	storeClientListAdd(e, asState);
-	fwdStart(-1, e, asState->request, no_addr, no_addr);
+	fwdStart(-1, e, asState->request);
     } else {
 	storeLockObject(e);
 	storeClientListAdd(e, asState);
Index: squid/src/async_io.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/async_io.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/async_io.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/async_io.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: async_io.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: async_io.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 32    Asynchronous Disk I/O
  * AUTHOR: Pete Bentley <pete@demon.net>
@@ -53,7 +53,6 @@
     AIOCB *done_handler;
     void *done_handler_data;
     aio_result_t result;
-    void *tag;
 } aio_ctrl_t;
 
 struct {
@@ -76,9 +75,17 @@
 static int initialised = 0;
 static OBJH aioStats;
 static MemPool *aio_ctrl_pool;
+static void aioFDWasClosed(int fd);
 
 static void
-aioInit()
+aioFDWasClosed(int fd)
+{
+    if (fd_table[fd].flags.closing)
+	fd_close(fd);
+}
+
+void
+aioInit(void)
 {
     if (initialised)
 	return;
@@ -88,26 +95,25 @@
     initialised = 1;
 }
 
-
 void
-aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data, void *tag)
+aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data)
 {
     aio_ctrl_t *ctrlp;
     int ret;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.open++;
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = -2;
-    ctrlp->tag = tag;
     ctrlp->done_handler = callback;
     ctrlp->done_handler_data = callback_data;
     ctrlp->operation = _AIO_OPEN;
-    if (aio_open(path, oflag, mode, &(ctrlp->result)) < 0) {
+    cbdataLock(callback_data);
+    if (aio_open(path, oflag, mode, &ctrlp->result) < 0) {
 	ret = open(path, oflag, mode);
 	if (callback)
 	    (callback) (ctrlp->fd, callback_data, ret, errno);
+	cbdataUnlock(callback_data);
 	memPoolFree(aio_ctrl_pool, ctrlp);
 	return;
     }
@@ -121,20 +127,18 @@
 {
     aio_ctrl_t *ctrlp;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.close++;
-    aioCancel(fd, NULL);
+    aioCancel(fd);
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = fd;
-    ctrlp->tag = NULL;
     ctrlp->done_handler = NULL;
     ctrlp->done_handler_data = NULL;
     ctrlp->operation = _AIO_CLOSE;
-    if (aio_close(fd, &(ctrlp->result)) < 0) {
+    if (aio_close(fd, &ctrlp->result) < 0) {
 	close(fd);		/* Can't create thread - do a normal close */
 	memPoolFree(aio_ctrl_pool, ctrlp);
-	fd_was_closed(fd);
+	aioFDWasClosed(fd);
 	return;
     }
     ctrlp->next = used_list;
@@ -143,14 +147,15 @@
 }
 
 void
-aioCancel(int fd, void *tag)
+aioCancel(int fd)
 {
     aio_ctrl_t *curr;
     aio_ctrl_t *prev;
     aio_ctrl_t *next;
+    AIOCB *done_handler;
+    void *their_data;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.cancel++;
     prev = NULL;
     curr = used_list;
@@ -158,19 +163,23 @@
 	while (curr != NULL) {
 	    if (curr->fd == fd)
 		break;
-	    if (tag != NULL && curr->tag == tag)
-		break;
 	    prev = curr;
 	    curr = curr->next;
 	}
 	if (curr == NULL)
 	    break;
 
-	aio_cancel(&(curr->result));
-
-	if (curr->done_handler)
-	    (curr->done_handler) (fd, curr->done_handler_data, -2, -2);
+	aio_cancel(&curr->result);
 
+	if ((done_handler = curr->done_handler)) {
+	    their_data = curr->done_handler_data;
+	    curr->done_handler = NULL;
+	    curr->done_handler_data = NULL;
+	    debug(0, 0) ("this be aioCancel\n");
+	    if (cbdataValid(their_data))
+		done_handler(fd, their_data, -2, -2);
+	    cbdataUnlock(their_data);
+	}
 	next = curr->next;
 	if (prev == NULL)
 	    used_list = next;
@@ -183,26 +192,26 @@
 
 
 void
-aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data)
+aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data, FREE * free_func)
 {
     aio_ctrl_t *ctrlp;
     int seekmode;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.write++;
     for (ctrlp = used_list; ctrlp != NULL; ctrlp = ctrlp->next)
 	if (ctrlp->fd == fd)
 	    break;
     if (ctrlp != NULL) {
+	debug(0, 0) ("aioWrite: EWOULDBLOCK\n");
 	errno = EWOULDBLOCK;
 	if (callback)
 	    (callback) (fd, callback_data, -1, errno);
+	free_func(bufp);
 	return;
     }
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = fd;
-    ctrlp->tag = NULL;
     ctrlp->done_handler = callback;
     ctrlp->done_handler_data = callback_data;
     ctrlp->operation = _AIO_WRITE;
@@ -212,17 +221,22 @@
 	seekmode = SEEK_END;
 	offset = 0;
     }
-    if (aio_write(fd, bufp, len, offset, seekmode, &(ctrlp->result)) < 0) {
+    cbdataLock(callback_data);
+    if (aio_write(fd, bufp, len, offset, seekmode, &ctrlp->result) < 0) {
 	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)
 	    errno = EWOULDBLOCK;
 	if (callback)
 	    (callback) (fd, callback_data, -1, errno);
+	cbdataUnlock(callback_data);
 	memPoolFree(aio_ctrl_pool, ctrlp);
-	return;
-    }
-    ctrlp->next = used_list;
-    used_list = ctrlp;
-    return;
+    } else {
+	ctrlp->next = used_list;
+	used_list = ctrlp;
+    }
+    /*
+     * aio_write copies the buffer so we can free it here
+     */
+    free_func(bufp);
 }				/* aioWrite */
 
 
@@ -232,8 +246,7 @@
     aio_ctrl_t *ctrlp;
     int seekmode;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.read++;
     for (ctrlp = used_list; ctrlp != NULL; ctrlp = ctrlp->next)
 	if (ctrlp->fd == fd)
@@ -246,7 +259,6 @@
     }
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = fd;
-    ctrlp->tag = NULL;
     ctrlp->done_handler = callback;
     ctrlp->done_handler_data = callback_data;
     ctrlp->operation = _AIO_READ;
@@ -256,11 +268,13 @@
 	seekmode = SEEK_CUR;
 	offset = 0;
     }
-    if (aio_read(fd, bufp, len, offset, seekmode, &(ctrlp->result)) < 0) {
+    cbdataLock(callback_data);
+    if (aio_read(fd, bufp, len, offset, seekmode, &ctrlp->result) < 0) {
 	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)
 	    errno = EWOULDBLOCK;
 	if (callback)
 	    (callback) (fd, callback_data, -1, errno);
+	cbdataUnlock(callback_data);
 	memPoolFree(aio_ctrl_pool, ctrlp);
 	return;
     }
@@ -270,24 +284,24 @@
 }				/* aioRead */
 
 void
-aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data, void *tag)
+aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data)
 {
     aio_ctrl_t *ctrlp;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.stat++;
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = -2;
-    ctrlp->tag = tag;
     ctrlp->done_handler = callback;
     ctrlp->done_handler_data = callback_data;
     ctrlp->operation = _AIO_STAT;
-    if (aio_stat(path, sb, &(ctrlp->result)) < 0) {
+    cbdataLock(callback_data);
+    if (aio_stat(path, sb, &ctrlp->result) < 0) {
 	if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL)
 	    errno = EWOULDBLOCK;
 	if (callback)
 	    (callback) (ctrlp->fd, callback_data, -1, errno);
+	cbdataUnlock(callback_data);
 	memPoolFree(aio_ctrl_pool, ctrlp);
 	return;
     }
@@ -301,8 +315,7 @@
 {
     aio_ctrl_t *ctrlp;
     char *path;
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.unlink++;
     ctrlp = memPoolAlloc(aio_ctrl_pool);
     ctrlp->fd = -2;
@@ -310,9 +323,11 @@
     ctrlp->done_handler_data = callback_data;
     ctrlp->operation = _AIO_UNLINK;
     path = xstrdup(pathname);
-    if (aio_unlink(path, &(ctrlp->result)) < 0) {
+    cbdataLock(callback_data);
+    if (aio_unlink(path, &ctrlp->result) < 0) {
 	int ret = unlink(path);
 	(callback) (ctrlp->fd, callback_data, ret, errno);
+	cbdataUnlock(callback_data);
 	memPoolFree(aio_ctrl_pool, ctrlp);
 	xfree(path);
 	return;
@@ -324,21 +339,22 @@
 
 
 void
-aioCheckCallbacks()
+aioCheckCallbacks(void)
 {
     aio_result_t *resultp;
     aio_ctrl_t *ctrlp;
     aio_ctrl_t *prev;
+    AIOCB *done_handler;
+    void *their_data;
 
-    if (!initialised)
-	aioInit();
+    assert(initialised);
     aio_counts.check_callback++;
     for (;;) {
 	if ((resultp = aio_poll_done()) == NULL)
 	    break;
 	prev = NULL;
 	for (ctrlp = used_list; ctrlp != NULL; prev = ctrlp, ctrlp = ctrlp->next)
-	    if (&(ctrlp->result) == resultp)
+	    if (&ctrlp->result == resultp)
 		break;
 	if (ctrlp == NULL)
 	    continue;
@@ -346,11 +362,17 @@
 	    used_list = ctrlp->next;
 	else
 	    prev->next = ctrlp->next;
-	if (ctrlp->done_handler)
-	    (ctrlp->done_handler) (ctrlp->fd, ctrlp->done_handler_data,
-		ctrlp->result.aio_return, ctrlp->result.aio_errno);
+	if ((done_handler = ctrlp->done_handler)) {
+	    their_data = ctrlp->done_handler_data;
+	    ctrlp->done_handler = NULL;
+	    ctrlp->done_handler_data = NULL;
+	    if (cbdataValid(their_data))
+		done_handler(ctrlp->fd, their_data,
+		    ctrlp->result.aio_return, ctrlp->result.aio_errno);
+	    cbdataUnlock(their_data);
+	}
 	if (ctrlp->operation == _AIO_CLOSE)
-	    fd_was_closed(ctrlp->fd);
+	    aioFDWasClosed(ctrlp->fd);
 	memPoolFree(aio_ctrl_pool, ctrlp);
     }
 }
@@ -367,6 +389,7 @@
     storeAppendPrintf(sentry, "stat\t%d\n", aio_counts.stat);
     storeAppendPrintf(sentry, "unlink\t%d\n", aio_counts.unlink);
     storeAppendPrintf(sentry, "check_callback\t%d\n", aio_counts.check_callback);
+    storeAppendPrintf(sentry, "queue\t%d\n", aio_get_queue_len());
 }
 
 /* Flush all pending I/O */
@@ -379,8 +402,14 @@
     debug(32, 1) ("aioSync: flushing pending I/O operations\n");
     do {
 	aioCheckCallbacks();
-    } while (aio_operations_pending());
+    } while (aio_sync());
     debug(32, 1) ("aioSync: done\n");
 }
 
+int
+aioQueueSize(void)
+{
+    return memPoolInUseCount(aio_ctrl_pool);
+}
+
 #endif /* USE_ASYNC_IO */
Index: squid/src/authenticate.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/authenticate.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/authenticate.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: authenticate.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: authenticate.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Duane Wessels
@@ -120,8 +120,8 @@
 	cachemgrRegister("authenticator",
 	    "User Authenticator Stats",
 	    authenticateStats, 0, 1);
+	init++;
     }
-    init++;
 }
 
 void
Index: squid/src/cache_cf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_cf.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/cache_cf.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/cache_cf.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: cache_cf.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -58,8 +58,6 @@
 
 static int http_header_first = 0;
 
-static void self_destruct(void);
-
 static void configDoConfigure(void);
 static void parse_refreshpattern(refresh_t **);
 static int parseTimeUnits(const char *unit);
@@ -78,8 +76,12 @@
 static void dump_http_header(StoreEntry * entry, const char *name, HttpHeaderMask header);
 static void parse_http_header(HttpHeaderMask * header);
 static void free_http_header(HttpHeaderMask * header);
+static void parse_sockaddr_in_list(sockaddr_in_list **);
+static void dump_sockaddr_in_list(StoreEntry *, const char *, const sockaddr_in_list *);
+static void free_sockaddr_in_list(sockaddr_in_list **);
+static int check_null_sockaddr_in_list(const sockaddr_in_list *);
 
-static void
+void
 self_destruct(void)
 {
     fatalf("Bungled %s line %d: %s",
@@ -157,12 +159,17 @@
  * defined
  */
 
-#define GetInteger(var) \
-	token = strtok(NULL, w_space); \
-	if( token == NULL) \
-		self_destruct(); \
-	if (sscanf(token, "%d", &var) != 1) \
-		self_destruct();
+int
+GetInteger(void)
+{
+    char *token = strtok(NULL, w_space);
+    int i;
+    if (token == NULL)
+	self_destruct();
+    if (sscanf(token, "%d", &i) != 1)
+	self_destruct();
+    return i;
+}
 
 int
 parseConfigFile(const char *file_name)
@@ -241,7 +248,7 @@
     if (Config.Program.redirect) {
 	if (Config.redirectChildren < 1) {
 	    Config.redirectChildren = 0;
-	    safe_free(Config.Program.redirect);
+	    wordlistDestroy(&Config.Program.redirect);
 	} else if (Config.redirectChildren > DefaultRedirectChildrenMax) {
 	    debug(3, 0) ("WARNING: redirect_children was set to a bad value: %d\n",
 		Config.redirectChildren);
@@ -273,11 +280,11 @@
     storeConfigure();
     if (Config2.Accel.on && !strcmp(Config.Accel.host, "virtual"))
 	vhost_mode = 1;
-    if (Config.Port.http == NULL)
+    if (Config.Sockaddr.http == NULL)
 	fatal("No http_port specified!");
     snprintf(ThisCache, sizeof(ThisCache), "%s:%d (%s)",
 	uniqueHostname(),
-	(int) Config.Port.http->i,
+	(int) ntohs(Config.Sockaddr.http->s.sin_port),
 	full_appname_string);
     /*
      * the extra space is for loop detection in client_side.c -- we search
@@ -285,7 +292,7 @@
      */
     snprintf(ThisCache2, sizeof(ThisCache), " %s:%d (%s)",
 	uniqueHostname(),
-	(int) Config.Port.http->i,
+	(int) ntohs(Config.Sockaddr.http->s.sin_port),
 	full_appname_string);
     if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF)
 	Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF;
@@ -303,15 +310,19 @@
 	debug(3, 0) ("WARNING: resetting 'maximum_single_addr_tries to 1\n");
 	Config.retry.maxtries = 1;
     }
+#if HEAP_REPLACEMENT
+    /* The non-LRU policies do not use referenceAge */
+#else
     if (Config.referenceAge < 300) {
 	debug(3, 0) ("WARNING: resetting 'reference_age' to 1 week\n");
 	Config.referenceAge = 86400 * 7;
     }
+#endif
     requirePathnameExists("MIME Config Table", Config.mimeTablePathname);
     requirePathnameExists("cache_dns_program", Config.Program.dnsserver);
     requirePathnameExists("unlinkd_program", Config.Program.unlinkd);
     if (Config.Program.redirect)
-	requirePathnameExists("redirect_program", Config.Program.redirect);
+	requirePathnameExists("redirect_program", Config.Program.redirect->key);
     if (Config.Program.authenticate)
 	requirePathnameExists("authenticate_program", Config.Program.authenticate->key);
     requirePathnameExists("Icon Directory", Config.icons.directory);
@@ -406,7 +417,7 @@
 	self_destruct();
     d = atof(token);
     m = u;			/* default to 'units' if none specified */
-    if (0 == d)
+    if (0.0 == d)
 	(void) 0;
     else if ((token = strtok(NULL, w_space)) == NULL)
 	debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",
@@ -664,7 +675,7 @@
 	if (sscanf(token, "%d", &i) != 1)
 	    self_destruct();
 	ptr->restore_bps = i;
-	GetInteger(i);
+	i = GetInteger();
 	ptr->max_bytes = i;
 	ptr++;
     }
@@ -731,8 +742,8 @@
     }
     while ((t = strtok(NULL, w_space))) {
 	if ((id = httpHeaderIdByNameDef(t, strlen(t))) == -1)
-	    id = HDR_OTHER;
-	if (allowed)
+	    debug(3, 0) ("parse_http_header: Ignoring unknown header '%s'\n", t);
+	else if (allowed)
 	    CBIT_CLR(*header, id);
 	else
 	    CBIT_SET(*header, id);
@@ -752,12 +763,16 @@
     int i;
     for (i = 0; i < swap.n_configured; i++) {
 	s = swap.swapDirs + i;
-	storeAppendPrintf(entry, "%s %s %d %d %d\n",
-	    name,
-	    s->path,
-	    s->max_size >> 10,
-	    s->l1,
-	    s->l2);
+	switch (s->type) {
+	case SWAPDIR_UFS:
+	case SWAPDIR_ASYNCUFS:
+	    storeUfsDirDump(entry, name, s);
+	    break;
+	default:
+	    debug(0, 0) ("dump_cachedir doesn't know about type %d\n",
+		(int) s->type);
+	    break;
+	}
     }
 }
 
@@ -773,71 +788,38 @@
     return s == NULL;
 }
 
-static void
-parse_cachedir(cacheSwap * swap)
+void
+allocate_new_swapdir(cacheSwap * swap)
 {
-    char *token;
-    char *path;
-    int i;
-    int size;
-    int l1;
-    int l2;
-    unsigned int read_only = 0;
-    SwapDir *tmp = NULL;
-    if ((path = strtok(NULL, w_space)) == NULL)
-	self_destruct();
-    GetInteger(i);
-    size = i << 10;		/* Mbytes to kbytes */
-    if (size <= 0)
-	fatal("parse_cachedir: invalid size value");
-    GetInteger(i);
-    l1 = i;
-    if (l1 <= 0)
-	fatal("parse_cachedir: invalid level 1 directories value");
-    GetInteger(i);
-    l2 = i;
-    if (l2 <= 0)
-	fatal("parse_cachedir: invalid level 2 directories value");
-    if ((token = strtok(NULL, w_space)))
-	if (!strcasecmp(token, "read-only"))
-	    read_only = 1;
-    for (i = 0; i < swap->n_configured; i++) {
-	tmp = swap->swapDirs + i;
-	if (!strcmp(path, tmp->path)) {
-	    /* just reconfigure it */
-	    if (size == tmp->max_size)
-		debug(3, 1) ("Cache dir '%s' size remains unchanged at %d KB\n",
-		    path, size);
-	    else
-		debug(3, 1) ("Cache dir '%s' size changed to %d KB\n",
-		    path, size);
-	    tmp->max_size = size;
-	    if (tmp->flags.read_only != read_only)
-		debug(3, 1) ("Cache dir '%s' now %s\n",
-		    path, read_only ? "Read-Only" : "Read-Write");
-	    tmp->flags.read_only = read_only;
-	    return;
-	}
-    }
     if (swap->swapDirs == NULL) {
 	swap->n_allocated = 4;
 	swap->swapDirs = xcalloc(swap->n_allocated, sizeof(SwapDir));
     }
     if (swap->n_allocated == swap->n_configured) {
+	SwapDir *tmp;
 	swap->n_allocated <<= 1;
 	tmp = xcalloc(swap->n_allocated, sizeof(SwapDir));
 	xmemcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir));
 	xfree(swap->swapDirs);
 	swap->swapDirs = tmp;
     }
-    tmp = swap->swapDirs + swap->n_configured;
-    tmp->path = xstrdup(path);
-    tmp->max_size = size;
-    tmp->l1 = l1;
-    tmp->l2 = l2;
-    tmp->flags.read_only = read_only;
-    tmp->swaplog_fd = -1;
-    swap->n_configured++;
+}
+
+static void
+parse_cachedir(cacheSwap * swap)
+{
+    char *type_str;
+    if ((type_str = strtok(NULL, w_space)) == NULL)
+	self_destruct();
+    if (0 == strcasecmp(type_str, "ufs")) {
+	storeUfsDirParse(swap);
+#if USE_ASYNC_IO
+    } else if (0 == strcasecmp(type_str, "asyncufs")) {
+	storeAufsDirParse(swap);
+#endif
+    } else {
+	fatalf("Unknown cache_dir type '%s'\n", type_str);
+    }
 }
 
 static void
@@ -850,9 +832,15 @@
 	return;
     for (i = 0; i < swap->n_configured; i++) {
 	s = swap->swapDirs + i;
-	if (s->swaplog_fd > -1) {
-	    file_close(s->swaplog_fd);
-	    s->swaplog_fd = -1;
+	switch (s->type) {
+	case SWAPDIR_UFS:
+	case SWAPDIR_ASYNCUFS:
+	    storeUfsDirFree(s);
+	    break;
+	default:
+	    debug(0, 0) ("dump_cachedir doesn't know about type %d\n",
+		(int) s->type);
+	    break;
 	}
 	xfree(s->path);
 	filemapFreeMemory(s->map);
@@ -923,7 +911,7 @@
     char *token = NULL;
     peer *p;
     int i;
-    ushortlist *u;
+    sockaddr_in_list *s;
     const char *me = null_string;	/* XXX */
     p = memAllocate(MEM_PEER);
     p->http_port = CACHE_HTTP_PORT;
@@ -936,13 +924,13 @@
     if ((token = strtok(NULL, w_space)) == NULL)
 	self_destruct();
     p->type = parseNeighborType(token);
-    GetInteger(i);
+    i = GetInteger();
     p->http_port = (u_short) i;
-    GetInteger(i);
+    i = GetInteger();
     p->icp.port = (u_short) i;
     if (strcmp(p->host, me) == 0) {
-	for (u = Config.Port.http; u; u = u->next) {
-	    if (p->http_port != u->i)
+	for (s = Config.Sockaddr.http; s; s = s->next) {
+	    if (p->http_port != ntohs(s->s.sin_port))
 		continue;
 	    debug(15, 0) ("parse_peer: Peer looks like myself: %s %s/%d/%d\n",
 		p->type, p->host, p->http_port, p->icp.port);
@@ -991,6 +979,12 @@
 #endif
 	} else if (!strncasecmp(token, "login=", 6)) {
 	    p->login = xstrdup(token + 6);
+	} else if (!strncasecmp(token, "connect-timeout=", 16)) {
+	    p->connect_timeout = atoi(token + 16);
+#if USE_CACHE_DIGESTS
+	} else if (!strncasecmp(token, "digest-url=", 11)) {
+	    p->digest_url = xstrdup(token + 11);
+#endif
 	} else {
 	    debug(3, 0) ("parse_peer: token='%s'\n", token);
 	    self_destruct();
@@ -1190,6 +1184,7 @@
     }
 }
 
+#if UNUSED_CODE
 static void
 dump_ushortlist(StoreEntry * entry, const char *name, ushortlist * u)
 {
@@ -1233,6 +1228,7 @@
 	xfree(u);
     }
 }
+#endif
 
 static void
 dump_int(StoreEntry * entry, const char *name, int var)
@@ -1243,9 +1239,8 @@
 static void
 parse_int(int *var)
 {
-    char *token;
     int i;
-    GetInteger(i);
+    i = GetInteger();
     *var = i;
 }
 
@@ -1275,7 +1270,6 @@
 }
 
 #define free_onoff free_int
-#define free_httpanonymizer free_int
 #define dump_eol dump_string
 #define free_eol free_string
 
@@ -1336,11 +1330,11 @@
     if (token == NULL)
 	self_destruct();
     pattern = xstrdup(token);
-    GetInteger(i);		/* token: min */
+    i = GetInteger();		/* token: min */
     min = (time_t) (i * 60);	/* convert minutes to seconds */
-    GetInteger(i);		/* token: pct */
+    i = GetInteger();		/* token: pct */
     pct = (double) i / 100.0;
-    GetInteger(i);		/* token: max */
+    i = GetInteger();		/* token: max */
     max = (time_t) (i * 60);	/* convert minutes to seconds */
     /* Options */
     while ((token = strtok(NULL, w_space)) != NULL) {
@@ -1482,9 +1476,8 @@
 static void
 parse_size_t(size_t * var)
 {
-    char *token;
     int i;
-    GetInteger(i);
+    i = GetInteger();
     *var = (size_t) i;
 }
 
@@ -1526,10 +1519,9 @@
 static void
 parse_ushort(u_short * var)
 {
-    char *token;
     int i;
 
-    GetInteger(i);
+    i = GetInteger();
     if (i < 0)
 	i = 0;
     *var = (u_short) i;
@@ -1574,7 +1566,9 @@
     char *token = strtok(NULL, w_space);
     if (token == NULL)
 	self_destruct();
-    if (!strcasecmp(token, "deny"))
+    if (!strcasecmp(token, "strip"))
+	*var = URI_WHITESPACE_STRIP;
+    else if (!strcasecmp(token, "deny"))
 	*var = URI_WHITESPACE_DENY;
     else if (!strcasecmp(token, "allow"))
 	*var = URI_WHITESPACE_ALLOW;
@@ -1597,8 +1591,10 @@
 	s = "encode";
     else if (var == URI_WHITESPACE_CHOP)
 	s = "chop";
-    else
+    else if (var == URI_WHITESPACE_DENY)
 	s = "deny";
+    else
+	s = "strip";
     storeAppendPrintf(entry, "%s %s\n", name, s);
 }
 
@@ -1621,6 +1617,72 @@
     return PEER_SIBLING;
 }
 
+static void
+parse_sockaddr_in_list(sockaddr_in_list ** head)
+{
+    char *token;
+    char *t;
+    char *host = NULL;
+    const struct hostent *hp;
+    int i;
+    sockaddr_in_list *s;
+    while ((token = strtok(NULL, w_space))) {
+	if ((t = strchr(token, ':'))) {
+	    /* host:port */
+	    host = token;
+	    *t = '\0';
+	    i = atoi(t + 1);
+	    if (i <= 0)
+		self_destruct();
+	} else if ((i = atoi(token)) > 0) {
+	    /* port */
+	} else {
+	    self_destruct();
+	}
+	s = xcalloc(1, sizeof(*s));
+	s->s.sin_port = htons(i);
+	if (NULL == host)
+	    s->s.sin_addr = any_addr;
+	else if (1 == safe_inet_addr(host, &s->s.sin_addr))
+	    (void) 0;
+	else if ((hp = gethostbyname(token)))	/* dont use ipcache */
+	    s->s.sin_addr = inaddrFromHostent(hp);
+	else
+	    self_destruct();
+	while (*head)
+	    head = &(*head)->next;
+	*head = s;
+    }
+}
+
+static void
+dump_sockaddr_in_list(StoreEntry * e, const char *n, const sockaddr_in_list * s)
+{
+    while (s) {
+	storeAppendPrintf(e, "%s %s:%d\n",
+	    n,
+	    inet_ntoa(s->s.sin_addr),
+	    ntohs(s->s.sin_port));
+	s = s->next;
+    }
+}
+
+static void
+free_sockaddr_in_list(sockaddr_in_list ** head)
+{
+    sockaddr_in_list *s;
+    while ((s = *head) != NULL) {
+	*head = s->next;
+	xfree(s);
+    }
+}
+
+static int
+check_null_sockaddr_in_list(const sockaddr_in_list * s)
+{
+    return NULL == s;
+}
+
 void
 configFreeMemory(void)
 {
Index: squid/src/cachemgr.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/cachemgr.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/cachemgr.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/cachemgr.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cachemgr.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: cachemgr.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 0     CGI Cache Manager
  * AUTHOR: Duane Wessels
@@ -239,7 +239,7 @@
     printf("for the Squid object cache.</P>\n");
     printf("<HR>\n");
     printf("<FORM METHOD=\"GET\" ACTION=\"%s\">\n", script_name);
-    printf("<TABLE BORDER=0>\n");
+    printf("<TABLE BORDER=\"0\" CELLPADDING=\"10\" CELLSPACING=\"1\">\n");
     printf("<TR><TH ALIGN=\"left\">Cache Host:</TH><TD><INPUT NAME=\"host\" ");
     printf("SIZE=30 VALUE=\"%s\"></TD></TR>\n", host);
     printf("<TR><TH ALIGN=\"left\">Cache Port:</TH><TD><INPUT NAME=\"port\" ");
Index: squid/src/cf.data.pre
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/cf.data.pre	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/cf.data.pre	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+# $Id: cf.data.pre,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -35,14 +35,14 @@
 	------------------
 
 	This is the default Squid configuration file. You may wish
-	to look at http://cache.is.co.za/squid/ for documentation,
-	or the Squid home page (http://squid.nlanr.net/) for the FAQ.
+	to look at the Squid home page (http://squid.nlanr.net/)
+	for the FAQ and other documentation.
 
 	The default Squid config file shows what the defaults for
 	various options happen to be.  If you don't need to change the
 	default, you shouldn't uncomment the line.  Doing so may cause
 	run-time problems.  In some cases "none" refers to no default
-	setting at all, whilst in other cases it refers to a valid
+	setting at all, while in other cases it refers to a valid
 	option - the comments for that keyword indicate if this is the
 	case.
 
@@ -54,17 +54,32 @@
 COMMENT_END
 
 NAME: http_port ascii_port
-TYPE: ushortlist
+TYPE: sockaddr_in_list
 DEFAULT: none
 DEFAULT_IF_NONE: 3128
-LOC: Config.Port.http
+LOC: Config.Sockaddr.http
 DOC_START
-	The port number where Squid will listen for HTTP client
-	requests.  Default is 3128, for httpd-accel mode use port 80.
-	May be overridden with -a on the command line.
-
-	You may specify multiple ports here, but they MUST all be on
-	a single line.
+	Usage:	port
+		hostname:port
+		1.2.3.4:port
+
+	The socket addresses where Squid will listen for HTTP client
+	requests.  You may specify multiple socket addresses.
+	There are three forms: port alone, hostname with port, and
+	IP address with port.  If you specify a hostname or IP
+	address, then Squid binds the socket to that specific
+	address.  This replaces the old 'tcp_incoming_address'
+	option.  Most likely, you do not need to bind to a specific
+	address, so you can use the port number alone.
+
+	The default port number is 3128.
+
+	If you are running Squid in accelerator mode, then you
+	probably want to listen on port 80 also, or instead.
+
+	The -a command line option will override the *first* port
+	number listed here.   That option will NOT override an IP
+	address, however.
 
 http_port 3128
 DOC_END
@@ -75,7 +90,7 @@
 DEFAULT: 3130
 LOC: Config.Port.icp
 DOC_START
-	The port number where Squid sends and receives ICP requests to
+	The port number where Squid sends and receives ICP queries to
 	and from neighbor caches.  Default is 3130.  To disable use
 	"0".  May be overridden with -u on the command line.
 
@@ -88,7 +103,7 @@
 DEFAULT: 4827
 LOC: Config.Port.htcp
 DOC_START
-	The port number where Squid sends and receives ICP requests to
+	The port number where Squid sends and receives HTCP queries to
 	and from neighbor caches.  Default is 4827.  To disable use
 	"0".
 
@@ -104,7 +119,7 @@
 DEFAULT: none
 DOC_START
 	This tag specifies a list of multicast groups which your server
-	should join to receive multicasted ICP requests.
+	should join to receive multicasted ICP queries.
 
 	NOTE!  Be very careful what you put here!  Be sure you
 	understand the difference between an ICP _query_ and an ICP
@@ -115,10 +130,7 @@
 	receive replies from multicast group members.
 
 	You must be very careful to NOT use a multicast address which
-	is already in use by another group of caches.  NLANR has been
-	assigned a block of multicast address space for use in Web
-	Caching.  Plese write to us at nlanr-cache@nlanr.net to receive
-	an address for your own use.
+	is already in use by another group of caches.
 
 	If you are unsure about multicast, please read the Multicast
 	chapter in the Squid FAQ (http://squid.nlanr.net/Squid/FAQ/).
@@ -131,12 +143,6 @@
 DOC_END
 
 
-NAME: tcp_incoming_address bind_address
-TYPE: address
-LOC: Config.Addrs.tcp_incoming
-DEFAULT: 0.0.0.0
-DOC_NONE
-
 NAME: tcp_outgoing_address outbound_address
 TYPE: address
 LOC: Config.Addrs.tcp_outgoing
@@ -157,8 +163,6 @@
 	Usage: tcp_incoming_address 10.20.30.40
 	       udp_outgoing_address fully.qualified.domain.name
 
-	tcp_incoming_address	is used for the HTTP socket which accepts
-				connections from clients and other caches.
 	tcp_outgoing_address	is used for connections made to remote
 				servers and other caches.
 	udp_incoming_address	is used for the ICP socket receiving packets
@@ -166,13 +170,15 @@
 	udp_outgoing_address	is used for ICP packets sent out to other
 				caches.
 
-	The default behaviour is to not bind to any specific address.
+	The default behavior is to not bind to any specific address.
 
 	NOTE, udp_incoming_address and udp_outgoing_address can not
 	have the same value (unless it is 0.0.0.0) since they both use
 	port 3130.
 
-tcp_incoming_address 0.0.0.0
+	NOTE, tcp_incoming_address has been removed.  You can now
+	specify IP addresses on the 'http_port' line.
+
 tcp_outgoing_address 0.0.0.0
 udp_incoming_address 0.0.0.0
 udp_outgoing_address 0.0.0.0
@@ -224,6 +230,8 @@
 		     no-netdb-exchange
 		     no-delay
 		     login=user:password
+		     connect-timeout=nn
+		     digest-url=url
 
 		     use 'proxy-only' to specify that objects fetched
 		     from this cache should not be saved locally.
@@ -233,7 +241,7 @@
 		     is 1, larger weights are favored more.
 
 		     use 'ttl=n' to specify a IP multicast TTL to use
-		     when sending an ICP request to this address.
+		     when sending an ICP queries to this address.
 		     Only useful when sending to a multicast group.
 		     Because we don't accept ICP replies from random
 		     hosts, you must configure other group members as
@@ -272,6 +280,15 @@
 		     use 'login=user:password' if this is a personal/workgroup
 		     proxy and your parent requires proxy authentication.
 
+		     use 'connect-timeout=nn' to specify a peer
+		     specific connect timeout (also see the
+		     peer_connect_timeout directive)
+
+		     use 'digest-url=url' to tell Squid to fetch the cache
+		     digest (if digests are enabled) for this host from
+		     the specified URL rather than the Squid default
+		     location.
+
 	NOTE: non-ICP neighbors must be specified as 'parent'.
 
 cache_peer hostname type 3128 3130
@@ -349,6 +366,23 @@
 icp_query_timeout 0
 DOC_END
 
+NAME: maximum_icp_query_timeout
+COMMENT: (msec)
+DEFAULT: 2000
+TYPE: int
+LOC: Config.Timeout.icp_query_max
+DOC_START
+	Normally the ICP query timeout is determined dynamically.  But
+	sometimes it can lead to very large values (say 5 seconds).
+	Use this option to put an upper limit on the dynamic timeout
+	value.  Do NOT use this option to always use a fixed (instead
+	of a dynamic) timeout value.
+
+	If 'icp_query_timeout' is set to zero, then this value is
+	ignored.
+icp_query_timeout 2000
+DOC_END
+
 NAME: mcast_icp_query_timeout
 COMMENT: (msec)
 DEFAULT: 2000
@@ -468,13 +502,6 @@
 	reached.  Thereafter, blocks will be used to store hot
 	objects.
 
-	The values of cache_mem_low and cache_mem_high (below) can be
-	used to tune the use of the memory pool.  When the high mark is
-	reached, in-transit and hot objects will be released to clear
-	space.  When an object transfer is completed, it will remain in
-	memory only if the current memory usage is below the low water
-	mark.
-
 	The default is 8 Megabytes.
 
 cache_mem  8 MB
@@ -494,12 +521,17 @@
 DEFAULT: 95
 LOC: Config.Swap.highWaterMark
 DOC_START
-	The low- and high-water marks for cache LRU replacement.  LRU
-	replacement begins when the high-water mark is reached and ends
-	when enough objects have been removed and the low-water mark is
-	reached. Defaults are 90% and 95%. If you have a large cache, 5%
-	could be hundreds of MB. If this is the case you may wish to
-	set these numbers closer together.
+
+	The low- and high-water marks for cache object replacement.
+	Replacement begins when the swap (disk) usage is above the
+	low-water mark and attempts to maintain utilization near the
+	low-water mark.  As swap utilization gets close to high-water
+	mark object eviction becomes more aggressive.  If utilization is
+	close to the low-water mark less replacement is done each time.
+	
+	Defaults are 90% and 95%. If you have a large cache, 5% could be
+	hundreds of MB. If this is the case you may wish to set these
+	numbers closer together.
 
 cache_swap_low  90
 cache_swap_high 95
@@ -518,6 +550,10 @@
 	hits).  If you wish to increase speed more than your want to
 	save bandwidth you should leave this low.
 
+	NOTE: if using the LFUDA replacement policy you should increase
+	this value to maximize the byte hit rate improvement of LFUDA!
+	See replacement_policy below for a discussion of this policy.
+
 maximum_object_size 4096 KB
 DOC_END
 
@@ -567,16 +603,22 @@
 NAME: cache_dir
 TYPE: cachedir
 DEFAULT: none
-DEFAULT_IF_NONE: @DEFAULT_SWAP_DIR@ 100 16 256
+DEFAULT_IF_NONE: ufs @DEFAULT_SWAP_DIR@ 100 16 256
 LOC: Config.cacheSwap
 DOC_START
 	Usage:
 	
-	cache_dir Directory-Name Mbytes Level-1 Level2
+	cache_dir Type Directory-Name Mbytes Level-1 Level2
 
 	You can specify multiple cache_dir lines to spread the
 	cache among different disk partitions.
 
+	Type specifies the kind of storage system to use.  Most
+	everyone will want to use "ufs" as the type.  If you are using
+	Async I/O (--enable async-io) on Linux or Solaris, then you may
+	want to try "asyncufs" as the type.  Async IO support may be
+	buggy, however, so beware.
+
 	'Directory' is a top-level directory where cache swap
 	files will be stored.  If you want to use an entire disk
 	for caching, then this can be the mount-point directory.
@@ -597,7 +639,7 @@
 	will be created under each first-level directory.  The default
 	is 256.
 
-cache_dir @DEFAULT_SWAP_DIR@ 100 16 256
+cache_dir ufs @DEFAULT_SWAP_DIR@ 100 16 256
 DOC_END
 
 
@@ -607,7 +649,7 @@
 LOC: Config.Log.access
 DOC_START
 	Logs the client request activity.  Contains an entry for
-	every HTTP and ICP request received.
+	every HTTP and ICP queries received.
 
 cache_access_log @DEFAULT_ACCESS_LOG@
 DOC_END
@@ -619,7 +661,7 @@
 LOC: Config.Log.log
 DOC_START
 	Cache logging file. This is where general information about
-	your cache's behaviour goes. You can increase the amount of data
+	your cache's behavior goes. You can increase the amount of data
 	logged to this file with the "debug_options" tag below.
 
 cache_log @DEFAULT_CACHE_LOG@
@@ -634,7 +676,7 @@
 	Logs the activities of the storage manager.  Shows which
 	objects are ejected from the cache, and which objects are
 	saved and for how long.  To disable, enter "none". There are
-	not really utilities to analyse this data, so you can safely
+	not really utilities to analyze this data, so you can safely
 	disable it.
 
 cache_store_log @DEFAULT_STORE_LOG@
@@ -683,7 +725,7 @@
 	programs use.  To disable/enable this emulation, set
 	emulate_httpd_log to 'off' or 'on'.  The default
 	is to use the native log format since it includes useful
-	information that Squid-specific log analysers use.
+	information that Squid-specific log analyzers use.
 
 emulate_httpd_log off
 DOC_END
@@ -801,7 +843,7 @@
 DOC_START
 	If you want the anonymous login password to be more informative
 	(and enable the use of picky ftp servers), set this to something
-	resonable for your domain, like wwwuser@somewhere.net
+	reasonable for your domain, like wwwuser@somewhere.net
 
 	The reason why this is domainless by default is that the
 	request can be made on the behalf of a user in any domain,
@@ -901,7 +943,7 @@
 LOC: Config.Program.pinger
 DOC_START
 	Specify the location of the executable for the pinger process.
-	This is only useful if you configured Squid (during compliation)
+	This is only useful if you configured Squid (during compilation)
 	with the '--enable-icmp' option.
 
 pinger_program @DEFAULT_PINGER@
@@ -909,7 +951,7 @@
 
 
 NAME: redirect_program
-TYPE: string
+TYPE: wordlist
 LOC: Config.Program.redirect
 DEFAULT: none
 DOC_START
@@ -940,12 +982,22 @@
 DEFAULT: on
 LOC: Config.onoff.redir_rewrites_host
 DOC_START
-	By default Squid rewrites any Host: header in redirected requests.
-	If you are running a accelerator then this may not be a wanted effect
-	of a redirector.
+	By default Squid rewrites any Host: header in redirected
+	requests.  If you are running a accelerator then this may
+	not be a wanted effect of a redirector.
 redirect_rewrites_host_header on
 DOC_END
 
+NAME: redirector_access
+TYPE: acl_access
+DEFAULT: none
+LOC: Config.accessList.redirector
+DOC_START
+	If defined, this access list specifies which requests are
+	sent to the redirector processes.  By default all requests
+	are sent.
+DOC_END
+
 
 NAME: authenticate_program
 TYPE: wordlist
@@ -998,6 +1050,28 @@
 authenticate_ttl 3600
 DOC_END
 
+NAME: authenticate_ip_ttl
+TYPE: int
+LOC: Config.authenticateIpTTL
+DEFAULT: 0
+DOC_START
+	With this option you control how long a proxy authentication
+	will be bound to a specific IP address. If a request using
+	the same user name is received during this time then access
+	will be denied and both users are required to reauthenticate
+	them selves.  The idea behind this is to make it annoying
+	for people to share their password to their friends, but
+	yet allow a dialup user to reconnect on a different dialup
+	port.
+
+	The default is 0 to disable the check. Recommended value
+	if you have dialup users are no more than 60 (seconds). If
+	all your users are stationary then higher values may be
+	used.
+
+authenticate_ip_ttl 0
+DOC_END
+
 COMMENT_START
  OPTIONS FOR TUNING THE CACHE
  -----------------------------------------------------------------------------
@@ -1021,17 +1095,60 @@
 DOC_END
 
 
-NAME: request_size
+NAME: request_header_max_size
 COMMENT: (KB)
 TYPE: b_size_t
-DEFAULT: 100 KB
-LOC: Config.maxRequestSize
+DEFAULT: 10 KB
+LOC: Config.maxRequestHeaderSize
 DOC_START
-	Maximum allowed request size in kilobytes.  If people are using
-	POST to upload files, then set this to the largest acceptable
-	filesize plus a few extra kbytes.
+	This specifies the maximum size for HTTP headers in a request.
+	Request headers are usually relatively small (about 512 bytes).
+	Placing a limit on the request header size will catch certain
+	bugs (for example with persistent connections) and possibly
+	buffer-overflow or denial-of-service attacks.
+request_header_max_size 10 KB
+DOC_END
 
-request_size 100 KB
+NAME: request_body_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 1 MB
+LOC: Config.maxRequestBodySize
+DOC_START
+	This specifies the maximum size for an HTTP request body.
+	In other words, the maximum size of a PUT/POST request.
+	A user who attempts to send a request with a body larger
+	than this limit receives an "Invalid Request" error message.
+	If you set this parameter to a zero, there will be no limit
+	imposed.
+request_body_max_size 1 MB
+DOC_END
+
+NAME: reply_body_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 0
+LOC: Config.maxReplyBodySize
+DOC_START
+	This option specifies the maximum size of a reply body.  It
+	can be used to prevent users from downloading very large files,
+	such as MP3's and movies.   The reply size is checked twice.
+	First when we get the reply headers, we check the
+	content-length value.  If the content length value exists and
+	is larger than this parameter, the request is denied and the
+	user receives an error message that says "the request or reply
+	is too large." If there is no content-length, and the reply
+	size exceeds this limit, the client's connection is just closed
+	and they will receive a partial reply.
+
+	NOTE: downstream caches probably can not detect a partial reply
+	if there is no content-length header, so they will cache
+	partial responses and give them out as hits.  You should NOT
+	use this option if you have downstream caches.
+
+	If you set this parameter to zero (the default), there will be
+	no limit imposed.
+reply_body_max_size 0
 DOC_END
 
 
@@ -1045,8 +1162,18 @@
 	By default, regular expressions are CASE-SENSITIVE.  To make
 	them case-insensitive, use the -i option.
 
-	min and max are specified in MINUTES.
-	percent is an integer number.
+	'Min' is the time (in minutes) an object without an explicit
+	expiry time should be considered fresh. The recommended
+	value is 0, any higher values may cause dynamic applications
+	to be erroneously cached unless the application designer
+	has taken the appropriate actions.
+
+	'Percent' is a percentage of the objects age (time since last
+	modification age) an object without explicit expiry time
+	will be considered fresh.
+
+	'Max' is an upper limit on how long objects without an explicit
+	expiry time will be considered fresh.
 
 	options: override-expire
 		 override-lastmod
@@ -1086,9 +1213,55 @@
 	match, then the default will be used.
 
 Default:
+NOCOMMENT_START
 refresh_pattern		^ftp:		1440	20%	10080
 refresh_pattern		^gopher:	1440	0%	1440
 refresh_pattern 	.		0	20%	4320
+NOCOMMENT_END
+DOC_END
+
+
+NAME: replacement_policy
+TYPE: string
+LOC: Config.replPolicy
+DEFAULT: LFUDA
+IFDEF: HEAP_REPLACEMENT
+DOC_START
+	The cache replacement policy parameter determines which
+	objects are evicted (replaced) when disk space is needed.
+	Squid used to have only a single replacement policy, LRU.
+	But when built with -DHEAP_REPLACEMENT you can choose
+	between two new, enhanced policies:
+
+		   GDSF: Greedy-Dual Size Frequency
+		   LFUDA: Least Frequently Used with Dynamic Aging
+
+	Both of these policies are frequency based rather than recency
+	based, and perform better than LRU.
+
+	The GDSF policy optimizes object hit rate by keeping smaller
+	popular objects in cache so it has a better chance of getting a
+	hit.  It achieves a lower byte hit rate than LFUDA though since
+	it evicts larger (possibly popular) objects.
+
+	The LFUDA policy keeps popular objects in cache regardless of
+	their size and thus optimizes byte hit rate at the expense of
+	hit rate since one large, popular object will prevent many
+	smaller, slightly less popular objects from being cached.
+
+	Both policies utilize a dynamic aging mechanism that prevents
+	cache pollution that can otherwise occur with frequency-based
+	replacement policies.
+
+	NOTE: if using the LFUDA replacement policy you should increase
+	the value of maximum_object_size above its default of 4096 KB to
+	to maximize the potential byte hit rate improvement of LFUDA.  
+
+	For more information about these cache replacement policies see
+	http://www.hpl.hp.com/techreports/1999/HPL-1999-69.html and
+	http://fog.hpl.external.hp.com/techreports/98/HPL-98-173.html.
+
+replacement_policy LFUDA
 DOC_END
 
 
@@ -1106,7 +1279,7 @@
 	The 'reference_age' parameter defines the maximum LRU age.  For
 	example, setting reference_age to '1 week' will cause objects
 	to be removed if they have not been accessed for a week or
-	more.  The default value is one month.
+	more.  The default value is one year.
 
 	Specify a number here, followed by units of time.  For example:
 		1 week
@@ -1114,7 +1287,10 @@
 		4 months
 		2.2 hours
 
-reference_age 1 month
+	NOTE: this parameter is not used when using the enhanced
+	replacement policies, GDSH or LFUDA.
+
+reference_age 1 year
 DOC_END
 
 
@@ -1250,6 +1426,19 @@
 connect_timeout 120 seconds
 DOC_END
 
+NAME: peer_connect_timeout
+COMMENT: time-units
+TYPE: time_t
+LOC: Config.Timeout.peer_connect
+DEFAULT: 30 seconds
+DOC_START
+	This parameter specifies how long to wait for a pending TCP
+	connection to a peer cache.  The default is 30 seconds.   You
+	may also set different timeout values for individual neighbors
+	with the 'connect-timeout' option on a 'cache_peer' line.
+peer_connect_timeout 30 seconds
+DOC_END
+
 NAME: siteselect_timeout
 COMMENT: time-units
 TYPE: time_t
@@ -1298,7 +1487,7 @@
 DOC_START
 	The maximum amount of time that a client (browser) is allowed to
 	remain connected to the cache process.  This protects the Cache
-	from having alot of sockets (and hence file descriptors) tied up
+	from having a lot of sockets (and hence file descriptors) tied up
 	in a CLOSE_WAIT state from remote clients that go away without
 	properly shutting down (either because of a network failure or
 	because of a poor client implementation).  The default is one
@@ -1352,6 +1541,10 @@
 	to denial-of-service by having many ident requests going at
 	once.
 
+	Only src type ACL checks are fully supported.  A src_domain
+	ACL might work at times, but it will not always provide
+	the correct result.
+
 	This option may be disabled by using --disable-ident with
 	the configure script.
 ident_timeout 10 seconds
@@ -1423,6 +1616,7 @@
 	acl aclname urlpath_regex [-i] \.gif$ ...	# regex matching on URL path
 	acl aclname port     80 70 21 ...
 	acl aclname port     0-1024 ...		# ranges allowed
+	acl aclname myport   3128 ...		# (local socket TCP port)
 	acl aclname proto    HTTP FTP ...
 	acl aclname method   GET POST ...
 	acl aclname browser  [-i] regexp
@@ -1462,6 +1656,10 @@
 	  # 
 	  #	acl snmppublic snmp_community public
 
+	acl aclname maxconn number
+	  # This will be matched when the client's IP address has
+	  # more than <number> HTTP connections established.
+
 
 Examples:
 acl myexample dst_as 1241
@@ -1474,6 +1672,10 @@
 acl localhost src 127.0.0.1/255.255.255.255
 acl SSL_ports port 443 563
 acl Safe_ports port 80 21 443 563 70 210 1025-65535
+acl Safe_ports port 280		# http-mgmt
+acl Safe_ports port 488		# gss-http
+acl Safe_ports port 591		# filemaker
+acl Safe_ports port 777		# multiling http
 acl CONNECT method CONNECT
 NOCOMMENT_END
 DOC_END
@@ -1679,6 +1881,15 @@
 unique_hostname www-cache1.foo.org
 DOC_END
 
+
+NAME: hostname_aliases
+TYPE: wordlist
+LOC: Config.hostnameAliases
+DEFAULT: none
+DOC_START
+	A list of other DNS names that your cache has.
+DOC_END
+
 COMMENT_START
  OPTIONS FOR THE CACHE REGISTRATION SERVICE
  -----------------------------------------------------------------------------
@@ -1689,7 +1900,7 @@
 	create cache hierarchies.
 
 	An 'announcement' message is sent (via UDP) to the registration
-	service by Squid.  By default, the annoucement message is NOT
+	service by Squid.  By default, the announcement message is NOT
 	SENT unless you enable it with 'announce_period' below.
 
 	The announcement message includes your hostname, plus the
@@ -2097,7 +2308,7 @@
 DOC_START
 	Target number of objects per bucket in the store hash table.
 	Lowering this value increases the total number of buckets and
-	also the storage maintenance rate.  The default is 20.
+	also the storage maintenance rate.  The default is 50.
 
 store_objects_per_bucket 50
 DOC_END
@@ -2290,7 +2501,7 @@
 LOC: Config.anonymize_headers
 DEFAULT: none
 DOC_START
-        Usage: anonymize_headers allow|deny header_name ...
+	Usage: anonymize_headers allow|deny header_name ...
 
 	This option replaces the old 'http_anonymizer' option with
 	something that is much more configurable.  You may now
@@ -2301,7 +2512,7 @@
 	allow specific headers (thus denying all others), or you
 	may deny specific headers (thus allowing all others).
 
-	For example, to achieve the same behaviour as the old
+	For example, to achieve the same behavior as the old
 	'http_anonymizer standard' option, you should use:
 
 		anonymize_headers deny From Referer Server
@@ -2314,7 +2525,7 @@
 		anonymize_headers allow Content-Encoding Content-Length
 		anonymize_headers allow Content-Type Date Expires Host
 		anonymize_headers allow If-Modified-Since Last-Modified
-		anonymize_headers allow Location Pragma Accept Charset
+		anonymize_headers allow Location Pragma Accept
 		anonymize_headers allow Accept-Encoding Accept-Language
 		anonymize_headers allow Content-Language Mime-Version
 		anonymize_headers allow Retry-After Title Connection
@@ -2359,8 +2570,8 @@
 DEFAULT: @DEFAULT_ERROR_DIR@
 DOC_START
 	If you wish to create your own versions of the default
-	(English) error files, either to customise them to suit your
-	language or company copy the template english files to another
+	(English) error files, either to customize them to suit your
+	language or company copy the template English files to another
 	directory and point this tag at them.
 DOC_END
 
@@ -2412,34 +2623,13 @@
 DOC_START
 	Squid can now serve statistics and status information via SNMP.
 	By default it listens to port 3401 on the machine. If you don't
-	wish to use SNMP, set this to '-1'.
+	wish to use SNMP, set this to "0".
 
 	NOTE: SNMP support requires use the --enable-snmp configure
 	command line option.
 snmp_port 3401
 DOC_END
 
-NAME: forward_snmpd_port
-TYPE: ushort
-LOC: Config.Snmp.localPort
-DEFAULT: 0
-IFDEF: SQUID_SNMP
-DOC_START
-	This configures whether we should be forwarding SNMP requests
-	to another snmpd. The reason for putting this piece of
-	functionality into Squid was to enable access to the system's
-	installed snmpd with minimal changes.  This option is turned
-	off by default, check with your /etc/services for your system's
-	snmp port (usually 161).  We do not use getservbyname() to
-	allow you to set Squid into port 161 and your system's snmpd to
-	another port by changing /etc/services.
-
-	WARNING: Because of Squid acting as a proxy snmpd for system
-	you have to do security checks on THIS snmpd for all objects.
-	Check your snmp_config_file.
-forward_snmpd_port 0
-DOC_END
-
 NAME: snmp_access
 TYPE: acl_access
 LOC: Config.accessList.snmp
@@ -2455,7 +2645,7 @@
 	snmp_access allow|deny [!]aclname ...
 
 Example:
-snmp_access allow public localhost
+snmp_access allow snmppublic localhost
 snmp_access deny all
 DOC_END
 
@@ -2478,7 +2668,7 @@
 	snmp_outgoing_address	is used for SNMP packets returned to SNMP
 				agents.
 
-	The default behaviour is to not bind to any specific address.
+	The default behavior is to not bind to any specific address.
 
 	NOTE, snmp_incoming_address and snmp_outgoing_address can not have
 	the same value since they both use port 3130.
@@ -2497,6 +2687,54 @@
 	queried only when Squid starts up, not for every request.
 DOC_END
 
+NAME: wccp_router
+TYPE: address
+LOC: Config.Wccp.router
+DEFAULT: 0.0.0.0
+IFDEF: USE_WCCP
+DOC_START
+	Use this option to define your WCCP ``home'' router for
+	Squid.   Setting the 'wccp_router' to 0.0.0.0 (the default)
+	disables WCCP.
+wccp_router 0.0.0.0
+DOC_END
+
+NAME: wccp_incoming_address
+TYPE: address
+LOC: Config.Wccp.incoming
+DEFAULT: 0.0.0.0
+IFDEF: USE_WCCP
+DOC_NONE
+NAME: wccp_outgoing_address
+TYPE: address
+LOC: Config.Wccp.outgoing
+DEFAULT: 255.255.255.255
+IFDEF: USE_WCCP
+DOC_START
+        wccp_incoming_address   Use this option if you require WCCP
+				messages to be received on only one
+				interface.  Do NOT use this option if
+				you're unsure how many interfaces you
+				have, or if you know you have only one
+				interface.
+
+	wccp_outgoing_address	Use this option if you require WCCP
+				messages to be sent out on only one
+				interface.  Do NOT use this option if
+				you're unsure how many interfaces you
+				have, or if you know you have only one
+				interface.
+
+        The default behavior is to not bind to any specific address.
+
+        NOTE, wccp_incoming_address and wccp_outgoing_address can not have
+        the same value since they both use port 2048.
+
+wccp_incoming_address 0.0.0.0
+wccp_outgoing_address 0.0.0.0
+DOC_END
+
+
 COMMENT_START
  DELAY POOL PARAMETERS (all require DELAY_POOLS compilation option)
  -----------------------------------------------------------------------------
@@ -2560,7 +2798,7 @@
 LOC: Config.Delay
 DOC_START
 	This is used to determine which delay pool a request falls into.
-	The first matched delay pool is always used, ie, if a request falls
+	The first matched delay pool is always used, i.e., if a request falls
 	into delay pool number one, no more delay are checked, otherwise the
 	rest are checked in order of their delay pool number until they have
 	all been checked.  For example, if you want some_big_clients in delay
@@ -2700,11 +2938,13 @@
 NAME: uri_whitespace
 TYPE: uri_whitespace
 LOC: Config.uri_whitespace
-DEFAULT: deny
+DEFAULT: strip
 DOC_START
 	What to do with requests that have whitespace characters in the
 	URI.  Options:
 
+	strip:  The whitespace characters are stripped out of the URL.
+		This is the behavior recommended by RFC2616.
 	deny:   The request is denied.  The user receives an "Invalid
 		Request" message.
 	allow:  The request is allowed and the URI is not changed.  The
@@ -2718,7 +2958,7 @@
 	chop:	The request is allowed and the URI is chopped at the
 		first whitespace.  This might also be considered a
 		violation.
-uri_whitespace deny
+uri_whitespace strip
 DOC_END
 
 NAME: broken_posts
@@ -2756,13 +2996,24 @@
 	certain you understand what you are doing.
 DOC_END
 
+NAME: mcast_miss_ttl
+IFDEF: MULTICAST_MISS_TTL
+TYPE: ushort
+LOC: Config.mcast_miss.ttl
+DEFAULT: 16
+DOC_START
+	This is the time-to-live value for packets multicasted
+	when multicasting off cache miss URLs is enabled.  By
+	default this is set to 'site scope', i.e. 16.
+DOC_END
+
 NAME: mcast_miss_port
 IFDEF: MULTICAST_MISS_STREAM
 TYPE: ushort
 LOC: Config.mcast_miss.port
 DEFAULT: 3135
 DOC_START
-	This is the port number to be used in conjuction with
+	This is the port number to be used in conjunction with
 	'mcast_miss_addr'.
 DOC_END
 
@@ -2812,4 +3063,119 @@
 	and coredump files will be left there.
 DOC_END
 
+NAME: redirector_bypass
+TYPE: onoff
+LOC: Config.onoff.redirector_bypass
+DEFAULT: off
+DOC_START
+	When this is 'on', a request will not go through the
+	redirector if all redirectors are busy.  If this is 'off'
+	and the redirector queue grows too large, Squid will exit
+	with a FATAL error and ask you to increase the number of
+	redirectors.  You should only enable this if the redirectors
+	are not critical to your caching system.  If you use
+	redirectors for access control, and you enable this option,
+	then users may have access to pages that they should not
+	be allowed to request.
+DOC_END
+
+NAME: ignore_unknown_nameservers
+TYPE: onoff
+LOC: Config.onoff.ignore_unknown_nameservers
+DEFAULT: on
+DOC_START
+	By default Squid checks that DNS responses are received
+	from the same IP addresses that they are sent to.  If they
+	don't match, Squid ignores the response and writes a warning
+	message to cache.log.  You can allow responses from unknown
+	nameservers by setting this option to 'off'.
+ignore_unknown_nameservers on
+DOC_END
+
+NAME: digest_generation
+IFDEF: USE_CACHE_DIGESTS
+TYPE: onoff
+LOC: Config.onoff.digest_generation
+DEFAULT: on
+DOC_START
+	This controls whether the server will generate a Cache Digest
+	of its contents.  By default, Cache Digest generation is
+	enabled if Squid is compiled with USE_CACHE_DIGESTS defined.
+digest_generation on
+DOC_END
+
+NAME: digest_bits_per_entry
+IFDEF: USE_CACHE_DIGESTS
+TYPE: int
+LOC: Config.digest.bits_per_entry
+DEFAULT: 5
+DOC_START
+	This is the number of bits of the server's Cache Digest which
+	will be associated with the Digest entry for a given HTTP
+	Method and URL (public key) combination.  The default is 5.
+digest_bits_per_entry 5
+DOC_END
+
+NAME: digest_rebuild_period
+IFDEF: USE_CACHE_DIGESTS
+COMMENT: (seconds)
+TYPE: time_t
+LOC: Config.digest.rebuild_period
+DEFAULT: 1 hour
+DOC_START
+	This is the number of seconds between Cache Digest rebuilds.
+	By default the server's Digest is rebuilt every hour.
+digest_rebuild_period 1 hour
+DOC_END
+
+NAME: digest_rewrite_period
+COMMENT: (seconds)
+IFDEF: USE_CACHE_DIGESTS
+TYPE: time_t
+LOC: Config.digest.rewrite_period
+DEFAULT: 1 hour
+DOC_START
+	This is the number of seconds between Cache Digest writes to
+	disk.  By default the server's Digest is written to disk every
+	hour.
+digest_rewrite_period 1 hour
+DOC_END
+
+NAME: digest_swapout_chunk_size
+COMMENT: (bytes)
+TYPE: b_size_t
+IFDEF: USE_CACHE_DIGESTS
+LOC: Config.digest.swapout_chunk_size
+DEFAULT: 4096 bytes
+DOC_START
+	This is the number of bytes of the Cache Digest to write to
+	disk at a time.  It defaults to 4096 bytes (4KB), the Squid
+	default swap page.
+digest_swapout_chunk_size 4096 bytes
+DOC_END
+
+NAME: digest_rebuild_chunk_percentage
+COMMENT: (percent, 0-100)
+IFDEF: USE_CACHE_DIGESTS
+TYPE: int
+LOC: Config.digest.rebuild_chunk_percentage
+DEFAULT: 10
+DOC_START
+	This is the percentage of the Cache Digest to be scanned at a
+	time.  By default it is set to 10% of the Cache Digest.
+digest_rebuild_chunk_percentage 10
+DOC_END
+
+NAME: chroot
+TYPE: string
+LOC: Config.chroot_dir
+DEFAULT: none
+DOC_START
+	Use this to have Squid do a chroot() while initializing.  This
+	also causes Squid to fully drop root privileges after
+	initializing.  This means, for example, that if you use a HTTP
+	port less than 1024 and try to reconfigure, you will get an
+	error.
+DOC_END
 EOF
+
Index: squid/src/cf_gen.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf_gen.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/cf_gen.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/cf_gen.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: cf_gen.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: cf_gen.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: none
  * AUTHOR: Max Okumoto
Index: squid/src/client.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/client.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/client.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/client.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: client.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 0     WWW Client
  * AUTHOR: Harvest Derived
@@ -40,6 +40,7 @@
 #endif
 
 /* Local functions */
+static int client_comm_bind(int, char *);
 static int client_comm_connect(int, char *, u_short, struct timeval *);
 static void usage(const char *progname);
 static int Now(struct timeval *);
@@ -55,7 +56,7 @@
 usage(const char *progname)
 {
     fprintf(stderr,
-	"Usage: %s [-arsv] [-i IMS] [-h host] [-p port] [-m method] [-t count] [-I ping-interval] [-H 'strings'] url\n"
+	"Usage: %s [-arsv] [-i IMS] [-h remote host] [-l local host] [-p port] [-m method] [-t count] [-I ping-interval] [-H 'strings'] url\n"
 	"Options:\n"
 	"    -P file      PUT request.\n"
 	"    -a           Do NOT include Accept: header.\n"
@@ -64,6 +65,7 @@
 	"    -v           Verbose. Print outgoing message to stderr.\n"
 	"    -i IMS       If-Modified-Since time (in Epoch seconds).\n"
 	"    -h host      Retrieve URL from cache on hostname.  Default is localhost.\n"
+	"    -l host      Specify a local IP address to bind to.  Default is none.\n"
 	"    -p port      Port number of cache.  Default is %d.\n"
 	"    -m method    Request method, default is GET.\n"
 	"    -t count     Trace count cache-hops\n"
@@ -85,7 +87,8 @@
     int opt_noaccept = 0;
     int opt_put = 0;
     int opt_verbose = 0;
-    char url[BUFSIZ], msg[BUFSIZ], buf[BUFSIZ], hostname[BUFSIZ];
+    char *hostname, *localhost;
+    char url[BUFSIZ], msg[BUFSIZ], buf[BUFSIZ];
     char extra_hdrs[BUFSIZ];
     const char *method = "GET";
     extern char *optarg;
@@ -97,7 +100,8 @@
     long ping_min = 0, ping_max = 0, ping_sum = 0, ping_mean = 0;
 
     /* set the defaults */
-    strcpy(hostname, "localhost");
+    hostname = "localhost";
+    localhost = NULL;
     extra_hdrs[0] = '\0';
     port = CACHE_HTTP_PORT;
     to_stdout = 1;
@@ -112,14 +116,18 @@
 	strcpy(url, argv[argc - 1]);
 	if (url[0] == '-')
 	    usage(argv[0]);
-	while ((c = getopt(argc, argv, "ah:P:i:km:p:rsvt:g:p:I:H:?")) != -1)
+	while ((c = getopt(argc, argv, "ah:l:P:i:km:p:rsvt:g:p:I:H:?")) != -1)
 	    switch (c) {
 	    case 'a':
 		opt_noaccept = 1;
 		break;
-	    case 'h':		/* host:arg */
+	    case 'h':		/* remote host */
 		if (optarg != NULL)
-		    strcpy(hostname, optarg);
+		    hostname = optarg;
+		break;
+	    case 'l':		/* local host */
+		if (optarg != NULL)
+		    localhost = optarg;
 		break;
 	    case 's':		/* silent */
 		to_stdout = 0;
@@ -250,6 +258,10 @@
 	    perror("client: socket");
 	    exit(1);
 	}
+	if (localhost && client_comm_bind(conn, localhost) < 0) {
+	    perror("client: bind");
+	    exit(1);
+	}
 	if (client_comm_connect(conn, hostname, port, ping ? &tv1 : NULL) < 0) {
 	    if (errno == 0) {
 		fprintf(stderr, "client: ERROR: Cannot connect to %s:%d: Host unknown.\n", hostname, port);
@@ -336,6 +348,25 @@
 }
 
 static int
+client_comm_bind(int sock, char *local_host)
+{
+    static const struct hostent *hp = NULL;
+    static struct sockaddr_in from_addr;
+
+    /* Set up the source socket address from which to send. */
+    if (hp == NULL) {
+	from_addr.sin_family = AF_INET;
+
+	if ((hp = gethostbyname(local_host)) == 0) {
+	    return (-1);
+	}
+	xmemcpy(&from_addr.sin_addr, hp->h_addr, hp->h_length);
+	from_addr.sin_port = 0;
+    }
+    return bind(sock, (struct sockaddr *) &from_addr, sizeof(struct sockaddr_in));
+}
+
+static int
 client_comm_connect(int sock, char *dest_host, u_short dest_port, struct timeval *tvp)
 {
     static const struct hostent *hp = NULL;
@@ -380,7 +411,7 @@
 }
 
 static void
-set_our_signal()
+set_our_signal(void)
 {
 #if HAVE_SIGACTION
     struct sigaction sa;
Index: squid/src/client_db.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/client_db.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/client_db.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/client_db.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_db.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: client_db.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 0     Client Database
  * AUTHOR: Duane Wessels
@@ -91,6 +91,30 @@
     }
 }
 
+/*
+ * clientdbEstablished()
+ * This function tracks the number of currently established connections
+ * for a client IP address.  When a connection is accepted, call this
+ * with delta = 1.  When the connection is closed, call with delta =
+ * -1.  To get the current value, simply call with delta = 0.
+ */
+int
+clientdbEstablished(struct in_addr addr, int delta)
+{
+    char *key;
+    ClientInfo *c;
+    if (!Config.onoff.client_db)
+	return 0;
+    key = inet_ntoa(addr);
+    c = (ClientInfo *) hash_lookup(client_table, key);
+    if (c == NULL)
+	c = clientdbAdd(addr);
+    if (c == NULL)
+	debug_trap("clientdbUpdate: Failed to add entry");
+    c->n_established += delta;
+    return c->n_established;
+}
+
 #define CUTOFF_SECONDS 3600
 int
 clientdbCutoffDenied(struct in_addr addr)
@@ -147,6 +171,8 @@
     while ((c = (ClientInfo *) hash_next(client_table))) {
 	storeAppendPrintf(sentry, "Address: %s\n", c->key);
 	storeAppendPrintf(sentry, "Name: %s\n", fqdnFromAddr(c->addr));
+	storeAppendPrintf(sentry, "Currently established connections: %d\n",
+	    c->n_established);
 	storeAppendPrintf(sentry, "    ICP Requests %d\n",
 	    c->Icp.n_requests);
 	for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) {
@@ -230,18 +256,14 @@
 variable_list *
 snmp_meshCtblFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     static char key[15];
     ClientInfo *c = NULL;
     int aggr = 0;
     log_type l;
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-
     debug(49, 6) ("snmp_meshCtblFn: Current : \n");
     snmpDebugOid(6, Var->name, Var->name_length);
-
     snprintf(key, sizeof(key), "%d.%d.%d.%d", Var->name[LEN_SQ_NET + 3], Var->name[LEN_SQ_NET + 4],
 	Var->name[LEN_SQ_NET + 5], Var->name[LEN_SQ_NET + 6]);
     debug(49, 5) ("snmp_meshCtblFn: [%s] requested!\n", key);
@@ -254,22 +276,19 @@
     }
     switch (Var->name[LEN_SQ_NET + 2]) {
     case MESH_CTBL_ADDR:
-	Answer->type = SMI_IPADDRESS;
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	*(Answer->val.integer) = (snint) c->addr.s_addr;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->addr.s_addr,
+	    SMI_IPADDRESS);
 	break;
     case MESH_CTBL_HTBYTES:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Http.kbytes_out.kb;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Http.kbytes_out.kb,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_HTREQ:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Http.n_requests;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Http.n_requests,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_HTHITS:
 	aggr = 0;
@@ -277,47 +296,40 @@
 	    if (isTcpHit(l))
 		aggr += c->Http.result_hist[l];
 	}
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) aggr;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) aggr,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_HTHITBYTES:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Http.hit_kbytes_out.kb;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Http.hit_kbytes_out.kb,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_ICPBYTES:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Icp.kbytes_out.kb;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Icp.kbytes_out.kb,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_ICPREQ:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Icp.n_requests;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Icp.n_requests,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_ICPHITS:
 	aggr = c->Icp.result_hist[LOG_UDP_HIT];
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) aggr;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) aggr,
+	    SMI_COUNTER32);
 	break;
     case MESH_CTBL_ICPHITBYTES:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = (snint) c->Icp.hit_kbytes_out.kb;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) c->Icp.hit_kbytes_out.kb,
+	    SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
 	debug(49, 5) ("snmp_meshCtblFn: illegal column.\n");
-	return (NULL);
+	break;
     }
     return Answer;
 }
Index: squid/src/client_side.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/client_side.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/client_side.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: client_side.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -93,6 +93,8 @@
 static STCB clientSendMoreData;
 static STCB clientCacheHit;
 static void clientSetKeepaliveFlag(clientHttpRequest *);
+static void clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec, String boundary, MemBuf * mb);
+static void clientPackTermBound(String boundary, MemBuf * mb);
 static void clientInterpretRequestHeaders(clientHttpRequest *);
 static void clientProcessRequest(clientHttpRequest *);
 static void clientProcessExpired(void *data);
@@ -102,6 +104,7 @@
 static int clientCheckContentLength(request_t * r);
 static int httpAcceptDefer(void);
 static log_type clientProcessRequest2(clientHttpRequest * http);
+static int clientReplyBodyTooLarge(int clen);
 
 static int
 checkAccelOnly(clientHttpRequest * http)
@@ -120,7 +123,7 @@
 }
 
 #if USE_IDENT
-void
+static void
 clientIdentDone(const char *ident, void *data)
 {
     ConnStateData *conn = data;
@@ -136,17 +139,12 @@
 {
     clientHttpRequest *http = data;
     ConnStateData *conn = http->conn;
-    const char *browser;
     if (checkAccelOnly(http)) {
 	clientAccessCheckDone(0, http);
 	return;
     }
-    browser = httpHeaderGetStr(&http->request->header, HDR_USER_AGENT);
     http->acl_checklist = aclChecklistCreate(Config.accessList.http,
 	http->request,
-	conn->peer.sin_addr,
-	conn->me.sin_addr,
-	browser,
 	conn->ident);
 #if USE_IDENT
     /*
@@ -201,7 +199,7 @@
     ErrorState *err = NULL;
     debug(33, 2) ("The request %s %s is %s, because it matched '%s'\n",
 	RequestMethodStr[http->request->method], http->uri,
-	answer ? "ALLOWED" : "DENIED",
+	answer == ACCESS_ALLOWED ? "ALLOWED" : "DENIED",
 	AclMatchedName ? AclMatchedName : "NO ACL's");
     http->acl_checklist = NULL;
     if (answer == ACCESS_ALLOWED) {
@@ -277,12 +275,14 @@
 	httpHeaderAppend(&new_request->header, &old_request->header);
 	new_request->client_addr = old_request->client_addr;
 	new_request->my_addr = old_request->my_addr;
+	new_request->my_port = old_request->my_port;
 	new_request->flags.redirected = 1;
 	if (old_request->body) {
 	    new_request->body = xmalloc(old_request->body_sz);
 	    xmemcpy(new_request->body, old_request->body, old_request->body_sz);
 	    new_request->body_sz = old_request->body_sz;
 	}
+	new_request->content_length = old_request->content_length;
 	requestUnlink(old_request);
 	http->request = requestLink(new_request);
     }
@@ -326,13 +326,11 @@
     /* delay_id is already set on original store client */
     delaySetStoreClient(entry, http, delayClient(http->request));
 #endif
-    entry->lastmod = http->old_entry->lastmod;
+    http->request->lastmod = http->old_entry->lastmod;
     debug(33, 5) ("clientProcessExpired: lastmod %d\n", (int) entry->lastmod);
-    entry->refcount++;		/* EXPIRED CASE */
     http->entry = entry;
     http->out.offset = 0;
-    fwdStart(http->conn->fd, http->entry, http->request,
-	http->conn->peer.sin_addr, http->conn->me.sin_addr);
+    fwdStart(http->conn->fd, http->entry, http->request);
     /* Register with storage manager to receive updates when data comes in. */
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n");
@@ -356,7 +354,7 @@
     /* If the reply is a failure then send the old object as a last
      * resort */
     if (status >= 500 && status < 600) {
-	debug(33, 2) ("clientGetsOldEntry: YES, failure reply=%d\n", status);
+	debug(33, 3) ("clientGetsOldEntry: YES, failure reply=%d\n", status);
 	return 1;
     }
     /* If the reply is anything but "Not Modified" then
@@ -413,7 +411,6 @@
 	storeUnregister(entry, http);
 	storeUnlockObject(entry);
 	entry = http->entry = http->old_entry;
-	entry->refcount++;
     } else if (STORE_PENDING == entry->store_status && 0 == status) {
 	debug(33, 3) ("clientHandleIMSReply: Incomplete headers for '%s'\n", url);
 	if (size >= CLIENT_SOCK_SZ) {
@@ -424,7 +421,6 @@
 	    storeUnregister(entry, http);
 	    storeUnlockObject(entry);
 	    entry = http->entry = http->old_entry;
-	    entry->refcount++;
 	    /* continue */
 	} else {
 	    storeClientCopy(entry,
@@ -464,8 +460,9 @@
 	/* the client can handle this reply, whatever it is */
 	http->log_type = LOG_TCP_REFRESH_MISS;
 	if (HTTP_NOT_MODIFIED == mem->reply->sline.status) {
-	    http->old_entry->timestamp = squid_curtime;
-	    http->old_entry->refcount++;
+	    httpReplyUpdateOnNotModified(http->old_entry->mem_obj->reply,
+		mem->reply);
+	    storeTimestampsSet(http->old_entry);
 	    http->log_type = LOG_TCP_REFRESH_HIT;
 	}
 	storeUnregister(http->old_entry, http);
@@ -663,10 +660,6 @@
 	http->al.cache.size = http->out.size;
 	http->al.cache.code = http->log_type;
 	http->al.cache.msec = tvSubMsec(http->start, current_time);
-	if (request->user_ident[0])
-	    http->al.cache.ident = request->user_ident;
-	else
-	    http->al.cache.ident = conn->ident;
 	if (request) {
 	    Packer p;
 	    MemBuf mb;
@@ -677,6 +670,10 @@
 	    http->al.http.version = request->http_ver;
 	    http->al.headers.request = xstrdup(mb.buf);
 	    http->al.hier = request->hier;
+	    if (request->user_ident[0])
+		http->al.cache.ident = request->user_ident;
+	    else
+		http->al.cache.ident = conn->ident;
 	    packerClean(&p);
 	    memBufClean(&mb);
 	}
@@ -730,6 +727,7 @@
     clientHttpRequest *http;
     debug(33, 3) ("connStateFree: FD %d\n", fd);
     assert(connState != NULL);
+    clientdbEstablished(connState->peer.sin_addr, -1);	/* decrement */
     while ((http = connState->chr) != NULL) {
 	assert(http->conn == connState);
 	assert(connState->chr != connState->chr->next);
@@ -767,6 +765,7 @@
 	    no_cache++;
 	stringClean(&s);
     }
+    request->cache_control = httpHeaderGetCc(req_hdr);
     if (request->cache_control)
 	if (EBIT_TEST(request->cache_control->mask, CC_NO_CACHE))
 	    no_cache++;
@@ -818,7 +817,6 @@
 	stringClean(&s);
     }
 #endif
-    request->cache_control = httpHeaderGetCc(req_hdr);
     if (request->method == METHOD_TRACE) {
 	request->max_forwards = httpHeaderGetInt(req_hdr, HDR_MAX_FORWARDS);
     }
@@ -856,12 +854,21 @@
 static int
 clientCheckContentLength(request_t * r)
 {
-    /* We only require a content-length for "upload" methods */
-    if (!pumpMethod(r->method))
+    int has_cont_len = (r->content_length >= 0);
+    switch (r->method) {
+    case METHOD_PUT:
+    case METHOD_POST:
+	/* PUT/POST requires a request entity */
+	return has_cont_len;
+    case METHOD_GET:
+    case METHOD_HEAD:
+	/* We do not want to see a request entity on GET/HEAD requests */
+	return !has_cont_len;
+    default:
+	/* For other types of requests we don't care */
 	return 1;
-    if (httpHeaderGetInt(&r->header, HDR_CONTENT_LENGTH) < 0)
-	return 0;
-    return 1;
+    }
+    /* NOT REACHED */
 }
 
 static int
@@ -882,14 +889,16 @@
      */
     ch.src_addr = http->conn->peer.sin_addr;
     ch.my_addr = http->conn->me.sin_addr;
+    ch.my_port = ntohs(http->conn->me.sin_port);
     ch.request = http->request;
     /*
      * aclCheckFast returns 1 for ALLOW and 0 for DENY.  The default
      * is ALLOW, so we require 'no_cache DENY foo' in squid.conf
      * to indicate uncachable objects.
      */
-    if (!aclCheckFast(Config.accessList.noCache, &ch))
-	return 0;
+    if (Config.accessList.noCache)
+	if (!aclCheckFast(Config.accessList.noCache, &ch))
+	    return 0;
     if (req->protocol == PROTO_HTTP)
 	return httpCachable(method);
     /* FTP is always cachable */
@@ -995,6 +1004,45 @@
     return 0;
 }
 
+/* returns expected content length for multi-range replies
+ * note: assumes that httpHdrRangeCanonize has already been called
+ * warning: assumes that HTTP headers for individual ranges at the
+ *          time of the actuall assembly will be exactly the same as
+ *          the headers when clientMRangeCLen() is called */
+static int
+clientMRangeCLen(clientHttpRequest * http)
+{
+    int clen = 0;
+    HttpHdrRangePos pos = HttpHdrRangeInitPos;
+    const HttpHdrRangeSpec *spec;
+    MemBuf mb;
+
+    assert(http->entry->mem_obj);
+
+    memBufDefInit(&mb);
+    while ((spec = httpHdrRangeGetSpec(http->request->range, &pos))) {
+
+	/* account for headers for this range */
+	memBufReset(&mb);
+	clientPackRangeHdr(http->entry->mem_obj->reply,
+	    spec, http->range_iter.boundary, &mb);
+	clen += mb.size;
+
+	/* account for range content */
+	clen += spec->length;
+
+	debug(33, 6) ("clientMRangeCLen: (clen += %d + %d) == %d\n",
+	    mb.size, spec->length, clen);
+    }
+    /* account for the terminating boundary */
+    memBufReset(&mb);
+    clientPackTermBound(http->range_iter.boundary, &mb);
+    clen += mb.size;
+
+    memBufClean(&mb);
+    return clen;
+}
+
 /* adds appropriate Range headers if needed */
 static void
 clientBuildRangeHeader(clientHttpRequest * http, HttpReply * rep)
@@ -1021,12 +1069,14 @@
 	range_err = "too complex range header";
     /* get rid of our range specs on error */
     if (range_err) {
-	debug(33, 2) ("clientBuildRangeHeader: will not do ranges: %s.\n", range_err);
+	debug(33, 3) ("clientBuildRangeHeader: will not do ranges: %s.\n", range_err);
 	httpHdrRangeDestroy(http->request->range);
 	http->request->range = NULL;
     } else {
 	const int spec_count = http->request->range->specs.count;
-	debug(33, 2) ("clientBuildRangeHeader: range spec count: %d clen: %d\n",
+	int actual_clen = -1;
+
+	debug(33, 3) ("clientBuildRangeHeader: range spec count: %d virgin clen: %d\n",
 	    spec_count, rep->content_length);
 	assert(spec_count > 0);
 	/* ETags should not be returned with Partial Content replies? */
@@ -1038,11 +1088,9 @@
 	    assert(spec);
 	    /* append Content-Range */
 	    httpHeaderAddContRange(hdr, *spec, rep->content_length);
-	    /* set new Content-Length to the actual number of OCTETs
+	    /* set new Content-Length to the actual number of bytes
 	     * transmitted in the message-body */
-	    httpHeaderDelById(hdr, HDR_CONTENT_LENGTH);
-	    httpHeaderPutInt(hdr, HDR_CONTENT_LENGTH, spec->length);
-	    debug(33, 2) ("clientBuildRangeHeader: actual content length: %d\n", spec->length);
+	    actual_clen = spec->length;
 	} else {
 	    /* multipart! */
 	    /* generate boundary string */
@@ -1052,17 +1100,24 @@
 	    httpHeaderPutStrf(hdr, HDR_CONTENT_TYPE,
 		"multipart/byteranges; boundary=\"%s\"",
 		strBuf(http->range_iter.boundary));
-	    /* no need for Content-Length in multipart responses */
-	    /* but we must delete the original one if we cannot (yet)
-	     * calculate the actual length */
-	    httpHeaderDelById(hdr, HDR_CONTENT_LENGTH);
+	    /* Content-Length is not required in multipart responses
+	     * but it is always nice to have one */
+	    actual_clen = clientMRangeCLen(http);
 	}
+
+	/* replace Content-Length header */
+	assert(actual_clen >= 0);
+	httpHeaderDelById(hdr, HDR_CONTENT_LENGTH);
+	httpHeaderPutInt(hdr, HDR_CONTENT_LENGTH, actual_clen);
+	debug(33, 3) ("clientBuildRangeHeader: actual content length: %d\n", actual_clen);
     }
 }
 
-/* filters out unwanted entries from original reply header
+/*
+ * filters out unwanted entries from original reply header
  * adds extra entries if we have more info than origin server
- * adds Squid specific entries */
+ * adds Squid specific entries
+ */
 static void
 clientBuildReplyHeader(clientHttpRequest * http, HttpReply * rep)
 {
@@ -1105,20 +1160,29 @@
     if (request->range)
 	clientBuildRangeHeader(http, rep);
     /*
-     * Add Age header, not that our header must replace Age headers
-     * from other caches if any
+     * Add a estimated Age header on cache hits.
      */
-    if (http->entry->timestamp > 0) {
+    if (is_hit) {
+	/*
+	 * Remove any existing Age header sent by upstream caches
+	 * (note that the existing header is passed along unmodified
+	 * on cache misses)
+	 */
 	httpHeaderDelById(hdr, HDR_AGE);
 	/*
-	 * we do not follow HTTP/1.1 precisely here becuase we rely
-	 * on Date header when computing entry->timestamp; we should
-	 * be using _request_ time if Date header is not available
-	 * or if it is out of sync
-	 */
-	httpHeaderPutInt(hdr, HDR_AGE,
-	    http->entry->timestamp <= squid_curtime ?
-	    squid_curtime - http->entry->timestamp : 0);
+	 * This adds the calculated object age. Note that the details of the
+	 * age calculation is performed by adjusting the timestamp in
+	 * storeTimestampsSet(), not here.
+	 *
+	 * BROWSER WORKAROUND: IE sometimes hangs when receiving a 0 Age
+	 * header, so don't use it unless there is a age to report. Please
+	 * note that Age is only used to make a conservative estimation of
+	 * the objects age, so a Age: 0 header does not add any useful
+	 * information to the reply in any case.
+	 */
+	if (http->entry->timestamp < squid_curtime)
+	    httpHeaderPutInt(hdr, HDR_AGE,
+		squid_curtime - http->entry->timestamp);
     }
     /* Append X-Cache */
     httpHeaderPutStrf(hdr, HDR_X_CACHE, "%s from %s",
@@ -1127,14 +1191,12 @@
     /* Append X-Cache-Lookup: -- temporary hack, to be removed @?@ @?@ */
     httpHeaderPutStrf(hdr, HDR_X_CACHE_LOOKUP, "%s from %s:%d",
 	http->lookup_type ? http->lookup_type : "NONE",
-	getMyHostname(), Config.Port.http->i);
+	getMyHostname(), ntohs(Config.Sockaddr.http->s.sin_port));
 #endif
-    /*
-     * Clear keepalive for NON-HEAD requests with invalid content length
-     */
-    if (request->method != METHOD_HEAD)
-	if (http->entry->mem_obj->reply->content_length < 0)
-	    request->flags.proxy_keepalive = 0;
+    if (httpReplyBodySize(request->method, rep) < 0) {
+	debug(33, 3) ("clientBuildReplyHeader: can't keep-alive, unknown body size\n");
+	request->flags.proxy_keepalive = 0;
+    }
     /* Signal keep-alive if needed */
     httpHeaderPutStr(hdr,
 	http->flags.accel ? HDR_CONNECTION : HDR_PROXY_CONNECTION,
@@ -1155,21 +1217,25 @@
 clientBuildReply(clientHttpRequest * http, const char *buf, size_t size)
 {
     HttpReply *rep = httpReplyCreate();
-    if (httpReplyParse(rep, buf)) {
+    size_t k = headersEnd(buf, size);
+    if (k && httpReplyParse(rep, buf, k)) {
 	/* enforce 1.0 reply version */
 	rep->sline.version = 1.0;
 	/* do header conversions */
 	clientBuildReplyHeader(http, rep);
 	/* if we do ranges, change status to "Partial Content" */
 	if (http->request->range)
-	    httpStatusLineSet(&rep->sline, rep->sline.version, HTTP_PARTIAL_CONTENT, NULL);
+	    httpStatusLineSet(&rep->sline, rep->sline.version,
+		HTTP_PARTIAL_CONTENT, NULL);
     } else {
 	/* parsing failure, get rid of the invalid reply */
 	httpReplyDestroy(rep);
 	rep = NULL;
 	/* if we were going to do ranges, backoff */
-	if (http->request->range)
-	    clientBuildRangeHeader(http, rep);	/* will fail and destroy request->range */
+	if (http->request->range) {
+	    /* this will fail and destroy request->range */
+	    clientBuildRangeHeader(http, rep);
+	}
     }
     return rep;
 }
@@ -1312,7 +1378,7 @@
 	    storeUnlockObject(e);
 	    e = clientCreateStoreEntry(http, http->request->method, null_request_flags);
 	    http->entry = e;
-	    httpReplyParse(e->mem_obj->reply, mb.buf);
+	    httpReplyParse(e->mem_obj->reply, mb.buf, mb.size);
 	    storeAppend(e, mb.buf, mb.size);
 	    memBufClean(&mb);
 	    storeComplete(e);
@@ -1329,50 +1395,91 @@
     }
 }
 
+/* put terminating boundary for multiparts */
+static void
+clientPackTermBound(String boundary, MemBuf * mb)
+{
+    memBufPrintf(mb, "\r\n--%s--\r\n", strBuf(boundary));
+    debug(33, 6) ("clientPackTermBound: buf offset: %d\n", mb->size);
+}
+
+/* appends a "part" HTTP header (as in a multi-part/range reply) to the buffer */
+static void
+clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec, String boundary, MemBuf * mb)
+{
+    HttpHeader hdr;
+    Packer p;
+    assert(rep);
+    assert(spec);
+
+    /* put boundary */
+    debug(33, 5) ("clientPackRangeHdr: appending boundary: %s\n", strBuf(boundary));
+    /* rfc2046 requires to _prepend_ boundary with <crlf>! */
+    memBufPrintf(mb, "\r\n--%s\r\n", strBuf(boundary));
+
+    /* stuff the header with required entries and pack it */
+    httpHeaderInit(&hdr, hoReply);
+    if (httpHeaderHas(&rep->header, HDR_CONTENT_TYPE))
+	httpHeaderPutStr(&hdr, HDR_CONTENT_TYPE, httpHeaderGetStr(&rep->header, HDR_CONTENT_TYPE));
+    httpHeaderAddContRange(&hdr, *spec, rep->content_length);
+    packerToMemInit(&p, mb);
+    httpHeaderPackInto(&hdr, &p);
+    packerClean(&p);
+    httpHeaderClean(&hdr);
 
-/* extracts a "range" from *buf and appends them to mb, updating all offsets and such */
+    /* append <crlf> (we packed a header, not a reply) */
+    memBufPrintf(mb, crlf);
+}
+
+/*
+ * extracts a "range" from *buf and appends them to mb, updating
+ * all offsets and such.
+ */
 static void
-clientPackRange(clientHttpRequest * http, HttpHdrRangeIter * i, const char **buf, ssize_t * size, MemBuf * mb)
+clientPackRange(clientHttpRequest * http,
+    HttpHdrRangeIter * i,
+    const char **buf,
+    ssize_t * size,
+    MemBuf * mb)
 {
-    const size_t copy_sz = i->debt_size <= *size ? i->debt_size : *size;
+    const ssize_t copy_sz = i->debt_size <= *size ? i->debt_size : *size;
     off_t body_off = http->out.offset - i->prefix_size;
     assert(*size > 0);
     assert(i->spec);
-    /* intersection of "have" and "need" ranges must not be empty */
+    /*
+     * intersection of "have" and "need" ranges must not be empty
+     */
     assert(body_off < i->spec->offset + i->spec->length);
     assert(body_off + *size > i->spec->offset);
-    /* put boundary and headers at the beginning of range in a multi-range */
+    /*
+     * put boundary and headers at the beginning of a range in a
+     * multi-range
+     */
     if (http->request->range->specs.count > 1 && i->debt_size == i->spec->length) {
-	HttpReply *rep = http->entry->mem_obj ?		/* original reply */
-	http->entry->mem_obj->reply : NULL;
-	HttpHeader hdr;
-	Packer p;
-	assert(rep);
-	/* put boundary */
-	debug(33, 5) ("clientPackRange: appending boundary: %s\n", strBuf(i->boundary));
-	/* rfc2046 requires to _prepend_ boundary with <crlf>! */
-	memBufPrintf(mb, "\r\n--%s\r\n", strBuf(i->boundary));
-	httpHeaderInit(&hdr, hoReply);
-	if (httpHeaderHas(&rep->header, HDR_CONTENT_TYPE))
-	    httpHeaderPutStr(&hdr, HDR_CONTENT_TYPE, httpHeaderGetStr(&rep->header, HDR_CONTENT_TYPE));
-	httpHeaderAddContRange(&hdr, *i->spec, rep->content_length);
-	packerToMemInit(&p, mb);
-	httpHeaderPackInto(&hdr, &p);
-	packerClean(&p);
-	httpHeaderClean(&hdr);
-	/* append <crlf> (we packed a header, not a reply */
-	memBufPrintf(mb, crlf);
+	assert(http->entry->mem_obj);
+	clientPackRangeHdr(
+	    http->entry->mem_obj->reply,	/* original reply */
+	    i->spec,		/* current range */
+	    i->boundary,	/* boundary, the same for all */
+	    mb
+	    );
     }
-    /* append */
+    /*
+     * append content
+     */
     debug(33, 3) ("clientPackRange: appending %d bytes\n", copy_sz);
     memBufAppend(mb, *buf, copy_sz);
-    /* update offsets */
+    /*
+     * update offsets
+     */
     *size -= copy_sz;
     i->debt_size -= copy_sz;
     body_off += copy_sz;
     *buf += copy_sz;
     http->out.offset = body_off + i->prefix_size;	/* sync */
-    /* paranoid check */
+    /*
+     * paranoid check
+     */
     assert(*size >= 0 && i->debt_size >= 0);
 }
 
@@ -1408,9 +1515,9 @@
 	off_t start;		/* offset of still missing data */
 	assert(i->spec);
 	start = i->spec->offset + i->spec->length - i->debt_size;
-	debug(33, 2) ("clientPackMoreRanges: in:  offset: %d size: %d\n",
+	debug(33, 3) ("clientPackMoreRanges: in:  offset: %d size: %d\n",
 	    (int) body_off, size);
-	debug(33, 2) ("clientPackMoreRanges: out: start: %d spec[%d]: [%d, %d), len: %d debt: %d\n",
+	debug(33, 3) ("clientPackMoreRanges: out: start: %d spec[%d]: [%d, %d), len: %d debt: %d\n",
 	    (int) start, (int) i->pos, i->spec->offset, (int) (i->spec->offset + i->spec->length), i->spec->length, i->debt_size);
 	assert(body_off <= start);	/* we did not miss it */
 	/* skip up to start */
@@ -1433,10 +1540,10 @@
 	}
     }
     assert(!i->debt_size == !i->spec);	/* paranoid sync condition */
-    debug(33, 2) ("clientPackMoreRanges: buf exhausted: in:  offset: %d size: %d need_more: %d\n",
+    debug(33, 3) ("clientPackMoreRanges: buf exhausted: in:  offset: %d size: %d need_more: %d\n",
 	(int) body_off, size, i->debt_size);
     if (i->debt_size) {
-	debug(33, 2) ("clientPackMoreRanges: need more: spec[%d]: [%d, %d), len: %d\n",
+	debug(33, 3) ("clientPackMoreRanges: need more: spec[%d]: [%d, %d), len: %d\n",
 	    (int) i->pos, i->spec->offset, (int) (i->spec->offset + i->spec->length), i->spec->length);
 	/* skip the data we do not need if possible */
 	if (i->debt_size == i->spec->length)	/* at the start of the cur. spec */
@@ -1445,12 +1552,24 @@
 	    assert(body_off == i->spec->offset + i->spec->length - i->debt_size);
     } else if (http->request->range->specs.count > 1) {
 	/* put terminating boundary for multiparts */
-	memBufPrintf(mb, "\r\n--%s--\r\n", strBuf(i->boundary));
+	clientPackTermBound(i->boundary, mb);
     }
     http->out.offset = body_off + i->prefix_size;	/* sync */
     return i->debt_size > 0;
 }
 
+static int
+clientReplyBodyTooLarge(int clen)
+{
+    if (0 == Config.maxReplyBodySize)
+	return 0;		/* disabled */
+    if (clen < 0)
+	return 0;		/* unknown */
+    if (clen > Config.maxReplyBodySize)
+	return 1;		/* too large */
+    return 0;
+}
+
 /*
  * accepts chunk of a http message in buf, parses prefix, filters headers and
  * such, writes processed message to the client's socket
@@ -1505,7 +1624,17 @@
 	    }
 	}
 	rep = clientBuildReply(http, buf, size);
-	if (rep) {
+	if (rep && clientReplyBodyTooLarge(rep->content_length)) {
+	    ErrorState *err = errorCon(ERR_TOO_BIG, HTTP_FORBIDDEN);
+	    err->request = requestLink(http->request);
+	    storeUnregister(http->entry, http);
+	    storeUnlockObject(http->entry);
+	    http->entry = clientCreateStoreEntry(http, http->request->method,
+		null_request_flags);
+	    errorAppendEntry(http->entry, err);
+	    httpReplyDestroy(rep);
+	    return;
+	} else if (rep) {
 	    body_size = size - rep->hdr_sz;
 	    assert(body_size >= 0);
 	    body_buf = buf + rep->hdr_sz;
@@ -1645,7 +1774,7 @@
     } else if ((done = clientCheckTransferDone(http)) != 0 || size == 0) {
 	debug(33, 5) ("clientWriteComplete: FD %d transfer is DONE\n", fd);
 	/* We're finished case */
-	if (http->entry->mem_obj->reply->content_length < 0) {
+	if (httpReplyBodySize(http->request->method, entry->mem_obj->reply) < 0) {
 	    debug(33, 5) ("clientWriteComplete: closing, content_length < 0\n");
 	    comm_close(fd);
 	} else if (!done) {
@@ -1660,6 +1789,8 @@
 	} else {
 	    comm_close(fd);
 	}
+    } else if (clientReplyBodyTooLarge((int) http->out.offset)) {
+	comm_close(fd);
     } else {
 	/* More data will be coming from primary server; register with 
 	 * storage manager. */
@@ -1806,7 +1937,7 @@
 	}
 	/* yes, continue */
 	http->log_type = LOG_TCP_MISS;
-    } else if (pumpMethod(r->method)) {
+    } else if (r->content_length > 0) {
 	http->log_type = LOG_TCP_MISS;
 	/* XXX oof, POST can be cached! */
 	pumpInit(fd, r, http->uri);
@@ -1820,11 +1951,11 @@
     if (NULL != http->entry) {
 	storeLockObject(http->entry);
 	storeCreateMemObject(http->entry, http->uri, http->log_uri);
+	http->entry->mem_obj->method = r->method;
 	storeClientListAdd(http->entry, http);
 #if DELAY_POOLS
 	delaySetStoreClient(http->entry, http, delayClient(r));
 #endif
-	http->entry->refcount++;
 	storeClientCopy(http->entry,
 	    http->out.offset,
 	    http->out.offset,
@@ -1879,7 +2010,6 @@
     }
     assert(http->out.offset == 0);
     http->entry = clientCreateStoreEntry(http, r->method, r->flags);
-    http->entry->refcount++;
     if (http->redirect.status) {
 	HttpReply *rep = httpReplyCreate();
 	storeReleaseRequest(http->entry);
@@ -1891,8 +2021,7 @@
     }
     if (http->flags.internal)
 	r->protocol = PROTO_INTERNAL;
-    fwdStart(http->conn->fd, http->entry, r,
-	http->conn->peer.sin_addr, http->conn->me.sin_addr);
+    fwdStart(http->conn->fd, http->entry, r);
 }
 
 static clientHttpRequest *
@@ -2126,10 +2255,10 @@
 	strcpy(http->uri, url);
 	http->flags.accel = 0;
     }
-    if (!stringHasWhitespace(http->uri))
+    if (!stringHasCntl(http->uri))
 	http->log_uri = xstrndup(http->uri, MAX_URL);
     else
-	http->log_uri = xstrndup(rfc1738_escape(http->uri), MAX_URL);
+	http->log_uri = xstrndup(rfc1738_escape_unescaped(http->uri), MAX_URL);
     debug(33, 5) ("parseHttpRequest: Complete request received\n");
     if (free_request)
 	safe_free(url);
@@ -2219,7 +2348,7 @@
 	/* Limit the number of concurrent requests to 2 */
 	for (H = &conn->chr, nrequests = 0; *H; H = &(*H)->next, nrequests++);
 	if (nrequests >= 2) {
-	    debug(33, 2) ("clientReadRequest: FD %d max concurrent requests reached\n", fd);
+	    debug(33, 3) ("clientReadRequest: FD %d max concurrent requests reached\n", fd);
 	    debug(33, 5) ("clientReadRequest: FD %d defering new request until one is done\n", fd);
 	    conn->defer.until = squid_curtime + 100;	/* Reset when a request is complete */
 	    break;
@@ -2278,27 +2407,34 @@
 	    request->flags.accelerated = http->flags.accel;
 	    if (!http->flags.internal) {
 		if (internalCheck(strBuf(request->urlpath))) {
-		    if (0 == strcasecmp(request->host, internalHostname()) &&
-			request->port == Config.Port.http->i) {
+		    if (internalHostnameIs(request->host) &&
+			request->port == ntohs(Config.Sockaddr.http->s.sin_port)) {
 			http->flags.internal = 1;
 		    } else if (internalStaticCheck(strBuf(request->urlpath))) {
 			xstrncpy(request->host, internalHostname(), SQUIDHOSTNAMELEN);
-			request->port = Config.Port.http->i;
+			request->port = ntohs(Config.Sockaddr.http->s.sin_port);
 			http->flags.internal = 1;
 		    }
 		}
 	    }
+	    /*
+	     * cache the Content-length value in request_t.
+	     */
+	    request->content_length = httpHeaderGetInt(&request->header,
+		HDR_CONTENT_LENGTH);
 	    request->flags.internal = http->flags.internal;
 	    safe_free(prefix);
 	    safe_free(http->log_uri);
 	    http->log_uri = xstrdup(urlCanonicalClean(request));
 	    request->client_addr = conn->peer.sin_addr;
 	    request->my_addr = conn->me.sin_addr;
+	    request->my_port = ntohs(conn->me.sin_port);
 	    request->http_ver = http->http_ver;
 	    if (!urlCheckRequest(request)) {
 		err = errorCon(ERR_UNSUP_REQ, HTTP_NOT_IMPLEMENTED);
 		err->src_addr = conn->peer.sin_addr;
 		err->request = requestLink(request);
+		request->flags.proxy_keepalive = 0;
 		http->al.http.code = err->http_status;
 		http->entry = clientCreateStoreEntry(http, request->method, null_request_flags);
 		errorAppendEntry(http->entry, err);
@@ -2321,13 +2457,12 @@
 	     */
 	    clientSetKeepaliveFlag(http);
 	    /*
-	     * break here for NON-GET because most likely there is a
-	     * reqeust body following and we don't want to parse it
-	     * as though it was new request
+	     * break here if the request has a content-length
+	     * because there is a reqeust body following and we
+	     * don't want to parse it as though it was new request.
 	     */
-	    if (request->method != METHOD_GET) {
-		int cont_len = httpHeaderGetInt(&request->header, HDR_CONTENT_LENGTH);
-		int copy_len = XMIN(conn->in.offset, cont_len);
+	    if (request->content_length >= 0) {
+		int copy_len = XMIN(conn->in.offset, request->content_length);
 		if (copy_len > 0) {
 		    assert(conn->in.offset >= copy_len);
 		    request->body_sz = copy_len;
@@ -2342,8 +2477,18 @@
 		 * be arriving on the client socket.  Lets cancel
 		 * the read handler until this request gets forwarded.
 		 */
-		if (request->body_sz < cont_len)
+		if (request->body_sz < request->content_length)
 		    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+		if (request->content_length < 0)
+		    (void) 0;
+		else if (request->content_length > Config.maxRequestBodySize) {
+		    err = errorCon(ERR_TOO_BIG, HTTP_REQUEST_ENTITY_TOO_LARGE);
+		    err->request = requestLink(request);
+		    http->entry = clientCreateStoreEntry(http,
+			METHOD_NONE, null_request_flags);
+		    errorAppendEntry(http->entry, err);
+		    break;
+		}
 	    }
 	    clientAccessCheck(http);
 	    continue;		/* while offset > 0 */
@@ -2354,14 +2499,13 @@
 	     */
 	    k = conn->in.size - 1 - conn->in.offset;
 	    if (k == 0) {
-		if (conn->in.offset >= Config.maxRequestSize) {
+		if (conn->in.offset >= Config.maxRequestHeaderSize) {
 		    /* The request is too large to handle */
-		    debug(33, 0) ("Request won't fit in buffer.\n");
-		    debug(33, 0) ("Config 'request_size'= %d bytes.\n",
-			Config.maxRequestSize);
-		    debug(33, 0) ("This request = %d bytes.\n",
+		    debug(33, 1) ("Request header is too large (%d bytes)\n",
 			(int) conn->in.offset);
-		    err = errorCon(ERR_INVALID_REQ, HTTP_REQUEST_ENTITY_TOO_LARGE);
+		    debug(33, 1) ("Config 'request_header_max_size'= %d bytes.\n",
+			Config.maxRequestHeaderSize);
+		    err = errorCon(ERR_TOO_BIG, HTTP_REQUEST_ENTITY_TOO_LARGE);
 		    http = parseHttpRequestAbort(conn, "error:request-too-large");
 		    /* add to the client request queue */
 		    for (H = &conn->chr; *H; H = &(*H)->next);
@@ -2374,7 +2518,7 @@
 		conn->in.size += REQUEST_BUF_SIZE;
 		conn->in.buf = xrealloc(conn->in.buf, conn->in.size);
 		/* XXX account conn->in.buf */
-		debug(33, 2) ("Handling a large request, offset=%d inbufsize=%d\n",
+		debug(33, 3) ("Handling a large request, offset=%d inbufsize=%d\n",
 		    (int) conn->in.offset, conn->in.size);
 		k = conn->in.size - 1 - conn->in.offset;
 	    }
@@ -2389,7 +2533,7 @@
 {
     ConnStateData *conn = data;
     ErrorState *err;
-    debug(33, 2) ("requestTimeout: FD %d: lifetime is expired.\n", fd);
+    debug(33, 3) ("requestTimeout: FD %d: lifetime is expired.\n", fd);
     if (fd_table[fd].rwstate) {
 	/*
 	 * Some data has been sent to the client, just close the FD
@@ -2418,6 +2562,10 @@
 	 * if we don't close() here, we still need a timeout handler!
 	 */
 	commSetTimeout(fd, 30, requestTimeout, conn);
+	/*
+	 * Aha, but we don't want a read handler!
+	 */
+	commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
     }
 }
 
@@ -2475,11 +2623,13 @@
 #if USE_IDENT
 	identChecklist.src_addr = peer.sin_addr;
 	identChecklist.my_addr = me.sin_addr;
+	identChecklist.my_port = ntohs(me.sin_port);
 	if (aclCheckFast(Config.accessList.identLookup, &identChecklist))
 	    identStart(&me, &peer, clientIdentDone, connState);
 #endif
 	commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, connState, 0);
 	commSetDefer(fd, clientReadDefer, connState);
+	clientdbEstablished(peer.sin_addr, 1);
 	(*N)++;
     }
 }
@@ -2556,7 +2706,7 @@
 static int
 clientGotNotEnough(clientHttpRequest * http)
 {
-    int cl = http->entry->mem_obj->reply->content_length;
+    int cl = httpReplyBodySize(http->request->method, http->entry->mem_obj->reply);
     int hs = http->entry->mem_obj->reply->hdr_sz;
     assert(cl >= 0);
     if (http->out.offset < cl + hs)
@@ -2611,14 +2761,14 @@
 void
 clientHttpConnectionsOpen(void)
 {
-    ushortlist *u;
+    sockaddr_in_list *s;
     int fd;
-    for (u = Config.Port.http; u; u = u->next) {
+    for (s = Config.Sockaddr.http; s; s = s->next) {
 	enter_suid();
 	fd = comm_open(SOCK_STREAM,
 	    0,
-	    Config.Addrs.tcp_incoming,
-	    u->i,
+	    s->s.sin_addr,
+	    ntohs(s->s.sin_port),
 	    COMM_NONBLOCKING,
 	    "HTTP Socket");
 	leave_suid();
@@ -2627,8 +2777,10 @@
 	comm_listen(fd);
 	commSetSelect(fd, COMM_SELECT_READ, httpAccept, NULL, 0);
 	/*commSetDefer(fd, httpAcceptDefer, NULL); */
-	debug(1, 1) ("Accepting HTTP connections on port %d, FD %d.\n",
-	    (int) u->i, fd);
+	debug(1, 1) ("Accepting HTTP connections at %s, port %d, FD %d.\n",
+	    inet_ntoa(s->s.sin_addr),
+	    (int) ntohs(s->s.sin_port),
+	    fd);
 	HttpSockets[NHttpSockets++] = fd;
     }
     if (NHttpSockets < 1)
Index: squid/src/comm.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/comm.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/comm.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/comm.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: comm.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -39,12 +39,6 @@
 #include <netinet/tcp.h>
 #endif
 
-#if USE_ASYNC_IO
-#define MAX_POLL_TIME 10
-#else
-#define MAX_POLL_TIME 1000
-#endif
-
 typedef struct {
     char *host;
     u_short port;
@@ -166,11 +160,11 @@
 	case ENFILE:
 	case EMFILE:
 	    debug(50, 1) ("comm_open: socket failure: %s\n", xstrerror());
+	    fdAdjustReserved();
 	    break;
 	default:
 	    debug(50, 0) ("comm_open: socket failure: %s\n", xstrerror());
 	}
-	fdAdjustReserved();
 	return -1;
     }
     /* update fdstat */
@@ -308,12 +302,14 @@
     Counter.syscalls.sock.sockets++;
     if (fd2 < 0) {
 	debug(5, 0) ("commResetFD: socket: %s\n", xstrerror());
-	fdAdjustReserved();
+	if (ENFILE == errno || EMFILE == errno)
+	    fdAdjustReserved();
 	return 0;
     }
     if (dup2(fd2, cs->fd) < 0) {
 	debug(5, 0) ("commResetFD: dup2: %s\n", xstrerror());
-	fdAdjustReserved();
+	if (ENFILE == errno || EMFILE == errno)
+	    fdAdjustReserved();
 	return 0;
     }
     close(fd2);
@@ -569,9 +565,6 @@
 comm_close(int fd)
 {
     fde *F = NULL;
-#if USE_ASYNC_IO
-    int doaioclose = 1;
-#endif
     debug(5, 5) ("comm_close: FD %d\n", fd);
     assert(fd >= 0);
     assert(fd < Squid_MaxFD);
@@ -582,30 +575,13 @@
 	return;
     assert(F->flags.open);
     assert(F->type != FD_FILE);
-#ifdef USE_ASYNC_IO
-    if (F->flags.nolinger && F->flags.nonblocking)
-	doaioclose = 0;
-#endif
     F->flags.closing = 1;
     CommWriteStateCallbackAndFree(fd, COMM_ERR_CLOSING);
     commCallCloseHandlers(fd);
     if (F->uses)		/* assume persistent connect count */
 	pconnHistCount(1, F->uses);
     fd_close(fd);		/* update fdstat */
-#if defined(_SQUID_LINUX_)
-    /*
-     * michael@metal.iinet.net.au sez close() on
-     * network sockets never blocks.
-     */
     close(fd);
-#elif USE_ASYNC_IO
-    if (doaioclose)
-	aioClose(fd);
-    else
-	close(fd);
-#else
-    close(fd);
-#endif
     Counter.syscalls.sock.closes++;
 }
 
@@ -744,6 +720,23 @@
     return 0;
 }
 
+int
+commUnsetNonBlocking(int fd)
+{
+    int flags;
+    int dummy = 0;
+    if ((flags = fcntl(fd, F_GETFL, dummy)) < 0) {
+	debug(50, 0) ("FD %d: fcntl F_GETFL: %s\n", fd, xstrerror());
+	return COMM_ERROR;
+    }
+    if (fcntl(fd, F_SETFL, flags & (~SQUID_NONBLOCK)) < 0) {
+	debug(50, 0) ("commUnsetNonBlocking: FD %d: %s\n", fd, xstrerror());
+	return COMM_ERROR;
+    }
+    fd_table[fd].flags.nonblocking = 0;
+    return 0;
+}
+
 void
 commSetCloseOnExec(int fd)
 {
@@ -863,11 +856,7 @@
     state->handler_data = handler_data;
     state->free_func = free_func;
     cbdataLock(handler_data);
-#ifdef OPTIMISTIC_IO
-    commHandleWrite(fd, state);
-#else
     commSetSelect(fd, COMM_SELECT_WRITE, commHandleWrite, state, 0);
-#endif
 }
 
 /* a wrapper around comm_write to allow for MemBuf to be comm_written in a snap */
Index: squid/src/comm_select.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/comm_select.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/comm_select.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/comm_select.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_select.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: comm_select.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -55,13 +55,16 @@
 #endif
 static int fdIsHttp(int fd);
 static int fdIsIcp(int fd);
+static int fdIsDns(int fd);
 static int commDeferRead(int fd);
 static void checkTimeouts(void);
 static OBJH commIncomingStats;
 #if HAVE_POLL
 static int comm_check_incoming_poll_handlers(int nfds, int *fds);
+static void comm_poll_dns_incoming(void);
 #else
 static int comm_check_incoming_select_handlers(int nfds, int *fds);
+static void comm_select_dns_incoming(void);
 #endif
 
 static struct timeval zero_tv;
@@ -122,10 +125,13 @@
 #define INCOMING_FACTOR 5
 #define MAX_INCOMING_INTERVAL (MAX_INCOMING_INTEGER << INCOMING_FACTOR)
 static int icp_io_events = 0;
+static int dns_io_events = 0;
 static int http_io_events = 0;
 static int incoming_icp_interval = 16 << INCOMING_FACTOR;
+static int incoming_dns_interval = 16 << INCOMING_FACTOR;
 static int incoming_http_interval = 16 << INCOMING_FACTOR;
 #define commCheckICPIncoming (++icp_io_events > (incoming_icp_interval>> INCOMING_FACTOR))
+#define commCheckDNSIncoming (++dns_io_events > (incoming_dns_interval>> INCOMING_FACTOR))
 #define commCheckHTTPIncoming (++http_io_events > (incoming_http_interval>> INCOMING_FACTOR))
 
 static int
@@ -148,6 +154,14 @@
 }
 
 static int
+fdIsDns(int fd)
+{
+    if (fd == DnsSocket)
+	return 1;
+    return 0;
+}
+
+static int
 fdIsHttp(int fd)
 {
     int j;
@@ -158,6 +172,31 @@
     return 0;
 }
 
+#if DELAY_POOLS
+static int slowfdcnt = 0;
+static int slowfdarr[SQUID_MAXFD];
+
+static void
+commAddSlowFd(int fd)
+{
+    assert(slowfdcnt < SQUID_MAXFD);
+    slowfdarr[slowfdcnt++] = fd;
+}
+
+static int
+commGetSlowFd(void)
+{
+    int whichfd, retfd;
+
+    if (!slowfdcnt)
+	return -1;
+    whichfd = squid_random() % slowfdcnt;
+    retfd = slowfdarr[whichfd];
+    slowfdarr[whichfd] = slowfdarr[--slowfdcnt];
+    return retfd;
+}
+#endif
+
 #if HAVE_POLL
 static int
 comm_check_incoming_poll_handlers(int nfds, int *fds)
@@ -184,7 +223,7 @@
 	}
     }
     if (!nfds)
-	return incame;
+	return -1;
 #if !ALARM_UPDATES_TIME
     getCurrentTime();
 #endif
@@ -199,15 +238,17 @@
 	    if ((hdl = fd_table[fd].read_handler)) {
 		fd_table[fd].read_handler = NULL;
 		hdl(fd, &incame);
-	    } else
-		debug(5, 1) ("comm_poll_incoming: NULL read handler\n");
+	    } else if (pfds[i].events & POLLRDNORM)
+		debug(5, 1) ("comm_poll_incoming: FD %d NULL read handler\n",
+		    fd);
 	}
 	if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) {
 	    if ((hdl = fd_table[fd].write_handler)) {
 		fd_table[fd].write_handler = NULL;
 		hdl(fd, &incame);
-	    } else
-		debug(5, 1) ("comm_poll_incoming: NULL write handler\n");
+	    } else if (pfds[i].events & POLLWRNORM)
+		debug(5, 1) ("comm_poll_incoming: FD %d NULL write_handler\n",
+		    fd);
 	}
     }
     return incame;
@@ -270,6 +311,9 @@
 comm_poll(int msec)
 {
     struct pollfd pfds[SQUID_MAXFD];
+#if DELAY_POOLS
+    fd_set slowfds;
+#endif
     PF *hdl = NULL;
     int fd;
     int i;
@@ -277,6 +321,7 @@
     unsigned long nfds;
     int num;
     int callicp = 0, callhttp = 0;
+    int calldns = 0;
     static time_t last_timeout = 0;
     double timeout = current_dtime + (msec / 1000.0);
     double start;
@@ -288,19 +333,39 @@
 #if USE_ASYNC_IO
 	aioCheckCallbacks();
 #endif
+#if DELAY_POOLS
+	FD_ZERO(&slowfds);
+#endif
 	if (commCheckICPIncoming)
 	    comm_poll_icp_incoming();
+	if (commCheckDNSIncoming)
+	    comm_poll_dns_incoming();
 	if (commCheckHTTPIncoming)
 	    comm_poll_http_incoming();
-	callicp = callhttp = 0;
+	callicp = calldns = callhttp = 0;
 	nfds = 0;
 	maxfd = Biggest_FD + 1;
 	for (i = 0; i < maxfd; i++) {
 	    int events;
 	    events = 0;
 	    /* Check each open socket for a handler. */
-	    if (fd_table[i].read_handler && !commDeferRead(i))
-		events |= POLLRDNORM;
+	    if (fd_table[i].read_handler) {
+		switch (commDeferRead(i)) {
+		case 0:
+		    events |= POLLRDNORM;
+		    break;
+		case 1:
+		    break;
+#if DELAY_POOLS
+		case -1:
+		    events |= POLLRDNORM;
+		    FD_SET(i, &slowfds);
+		    break;
+#endif
+		default:
+		    fatalf("bad return value from commDeferRead(FD %d)\n", i);
+		}
+	    }
 	    if (fd_table[i].write_handler)
 		events |= POLLWRNORM;
 	    if (events) {
@@ -350,6 +415,10 @@
 		callicp = 1;
 		continue;
 	    }
+	    if (fdIsDns(fd)) {
+		calldns = 1;
+		continue;
+	    }
 	    if (fdIsHttp(fd)) {
 		callhttp = 1;
 		continue;
@@ -357,15 +426,23 @@
 	    F = &fd_table[fd];
 	    if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) {
 		debug(5, 6) ("comm_poll: FD %d ready for reading\n", fd);
-		if ((hdl = F->read_handler)) {
+		if (NULL == (hdl = F->read_handler))
+		    (void) 0;
+#if DELAY_POOLS
+		else if (FD_ISSET(fd, &slowfds))
+		    commAddSlowFd(fd);
+#endif
+		else {
 		    F->read_handler = NULL;
 		    hdl(fd, F->read_data);
 		    Counter.select_fds++;
+		    if (commCheckICPIncoming)
+			comm_poll_icp_incoming();
+		    if (commCheckDNSIncoming)
+			comm_poll_dns_incoming();
+		    if (commCheckHTTPIncoming)
+			comm_poll_http_incoming();
 		}
-		if (commCheckICPIncoming)
-		    comm_poll_icp_incoming();
-		if (commCheckHTTPIncoming)
-		    comm_poll_http_incoming();
 	    }
 	    if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) {
 		debug(5, 5) ("comm_poll: FD %d ready for writing\n", fd);
@@ -373,11 +450,13 @@
 		    F->write_handler = NULL;
 		    hdl(fd, F->write_data);
 		    Counter.select_fds++;
+		    if (commCheckICPIncoming)
+			comm_poll_icp_incoming();
+		    if (commCheckDNSIncoming)
+			comm_poll_dns_incoming();
+		    if (commCheckHTTPIncoming)
+			comm_poll_http_incoming();
 		}
-		if (commCheckICPIncoming)
-		    comm_poll_icp_incoming();
-		if (commCheckHTTPIncoming)
-		    comm_poll_http_incoming();
 	    }
 	    if (revents & POLLNVAL) {
 		close_handler *ch;
@@ -406,14 +485,34 @@
 	}
 	if (callicp)
 	    comm_poll_icp_incoming();
+	if (calldns)
+	    comm_poll_dns_incoming();
 	if (callhttp)
 	    comm_poll_http_incoming();
+#if DELAY_POOLS
+	while ((fd = commGetSlowFd()) != -1) {
+	    fde *F = &fd_table[fd];
+	    debug(5, 6) ("comm_select: slow FD %d selected for reading\n", fd);
+	    if ((hdl = F->read_handler)) {
+		F->read_handler = NULL;
+		hdl(fd, F->read_data);
+		Counter.select_fds++;
+		if (commCheckICPIncoming)
+		    comm_poll_icp_incoming();
+		if (commCheckDNSIncoming)
+		    comm_poll_dns_incoming();
+		if (commCheckHTTPIncoming)
+		    comm_poll_http_incoming();
+	    }
+	}
+#endif
 #if !ALARM_UPDATES_TIME
 	getCurrentTime();
 	Counter.select_time += (current_dtime - start);
 #endif
 	return COMM_OK;
-    } while (timeout > current_dtime);
+    }
+    while (timeout > current_dtime);
     debug(5, 8) ("comm_poll: time out: %d.\n", squid_curtime);
     return COMM_TIMEOUT;
 }
@@ -446,7 +545,7 @@
 	}
     }
     if (maxfd++ == 0)
-	return incame;
+	return -1;
 #if !ALARM_UPDATES_TIME
     getCurrentTime();
 #endif
@@ -461,7 +560,8 @@
 		commUpdateReadBits(fd, NULL);
 		hdl(fd, &incame);
 	    } else {
-		debug(5, 1) ("comm_select_incoming: NULL read handler\n");
+		debug(5, 1) ("comm_select_incoming: FD %d NULL read handler\n",
+		    fd);
 	    }
 	}
 	if (FD_ISSET(fd, &write_mask)) {
@@ -470,7 +570,8 @@
 		commUpdateWriteBits(fd, NULL);
 		hdl(fd, &incame);
 	    } else {
-		debug(5, 1) ("comm_select_incoming: NULL write handler\n");
+		debug(5, 1) ("comm_select_incoming: FD %d NULL write handler\n",
+		    fd);
 	    }
 	}
     }
@@ -535,11 +636,15 @@
 {
     fd_set readfds;
     fd_set writefds;
+#if DELAY_POOLS
+    fd_set slowfds;
+#endif
     PF *hdl = NULL;
     int fd;
     int maxfd;
     int num;
     int callicp = 0, callhttp = 0;
+    int calldns = 0;
     int maxindex;
     int k;
     int j;
@@ -559,11 +664,16 @@
 #if USE_ASYNC_IO
 	aioCheckCallbacks();
 #endif
+#if DELAY_POOLS
+	FD_ZERO(&slowfds);
+#endif
 	if (commCheckICPIncoming)
 	    comm_select_icp_incoming();
+	if (commCheckDNSIncoming)
+	    comm_select_dns_incoming();
 	if (commCheckHTTPIncoming)
 	    comm_select_http_incoming();
-	callicp = callhttp = 0;
+	callicp = calldns = callhttp = 0;
 	maxfd = Biggest_FD + 1;
 	xmemcpy(&readfds, &global_readfds,
 	    howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
@@ -580,14 +690,30 @@
 		    continue;
 		/* Found a set bit */
 		fd = (j * FD_MASK_BITS) + k;
-		if (commDeferRead(fd))
+		switch (commDeferRead(fd)) {
+		case 0:
+		    break;
+		case 1:
 		    FD_CLR(fd, &readfds);
+		    break;
+#if DELAY_POOLS
+		case -1:
+		    FD_SET(fd, &slowfds);
+		    break;
+#endif
+		default:
+		    fatalf("bad return value from commDeferRead(FD %d)\n", fd);
+		}
 	    }
 	}
 #if DEBUG_FDBITS
 	for (i = 0; i < maxfd; i++) {
 	    /* Check each open socket for a handler. */
+#if DELAY_POOLS
+	    if (fd_table[i].read_handler && commDeferRead(i) != 1) {
+#else
 	    if (fd_table[i].read_handler && !commDeferRead(i)) {
+#endif
 		assert(FD_ISSET(i, &readfds));
 	    }
 	    if (fd_table[i].write_handler) {
@@ -641,10 +767,13 @@
 	    if ((tmask = fdsp[j]) == 0)
 		continue;	/* no bits here */
 	    for (k = 0; k < FD_MASK_BITS; k++) {
+		if (tmask == 0)
+		    break;	/* no more bits left */
 		if (!EBIT_TEST(tmask, k))
 		    continue;
 		/* Found a set bit */
 		fd = (j * FD_MASK_BITS) + k;
+		EBIT_CLR(tmask, k);	/* this will be done */
 #if DEBUG_FDBITS
 		debug(5, 9) ("FD %d bit set for reading\n", fd);
 		assert(FD_ISSET(fd, &readfds));
@@ -653,26 +782,34 @@
 		    callicp = 1;
 		    continue;
 		}
+		if (fdIsDns(fd)) {
+		    calldns = 1;
+		    continue;
+		}
 		if (fdIsHttp(fd)) {
 		    callhttp = 1;
 		    continue;
 		}
 		F = &fd_table[fd];
 		debug(5, 6) ("comm_select: FD %d ready for reading\n", fd);
-		if (F->read_handler) {
-		    hdl = F->read_handler;
+		if (NULL == (hdl = F->read_handler))
+		    (void) 0;
+#if DELAY_POOLS
+		else if (FD_ISSET(fd, &slowfds))
+		    commAddSlowFd(fd);
+#endif
+		else {
 		    F->read_handler = NULL;
 		    commUpdateReadBits(fd, NULL);
 		    hdl(fd, F->read_data);
 		    Counter.select_fds++;
+		    if (commCheckICPIncoming)
+			comm_select_icp_incoming();
+		    if (commCheckDNSIncoming)
+			comm_select_dns_incoming();
+		    if (commCheckHTTPIncoming)
+			comm_select_http_incoming();
 		}
-		if (commCheckICPIncoming)
-		    comm_select_icp_incoming();
-		if (commCheckHTTPIncoming)
-		    comm_select_http_incoming();
-		EBIT_CLR(tmask, k);	/* this bit is done */
-		if (tmask == 0)
-		    break;	/* and no more bits left */
 	    }
 	}
 	fdsp = (fd_mask *) & writefds;
@@ -680,10 +817,13 @@
 	    if ((tmask = fdsp[j]) == 0)
 		continue;	/* no bits here */
 	    for (k = 0; k < FD_MASK_BITS; k++) {
+		if (tmask == 0)
+		    break;	/* no more bits left */
 		if (!EBIT_TEST(tmask, k))
 		    continue;
 		/* Found a set bit */
 		fd = (j * FD_MASK_BITS) + k;
+		EBIT_CLR(tmask, k);	/* this will be done */
 #if DEBUG_FDBITS
 		debug(5, 9) ("FD %d bit set for writing\n", fd);
 		assert(FD_ISSET(fd, &writefds));
@@ -692,39 +832,93 @@
 		    callicp = 1;
 		    continue;
 		}
+		if (fdIsDns(fd)) {
+		    calldns = 1;
+		    continue;
+		}
 		if (fdIsHttp(fd)) {
 		    callhttp = 1;
 		    continue;
 		}
 		F = &fd_table[fd];
 		debug(5, 5) ("comm_select: FD %d ready for writing\n", fd);
-		if (F->write_handler) {
-		    hdl = F->write_handler;
+		if ((hdl = F->write_handler)) {
 		    F->write_handler = NULL;
 		    commUpdateWriteBits(fd, NULL);
 		    hdl(fd, F->write_data);
 		    Counter.select_fds++;
+		    if (commCheckICPIncoming)
+			comm_select_icp_incoming();
+		    if (commCheckDNSIncoming)
+			comm_select_dns_incoming();
+		    if (commCheckHTTPIncoming)
+			comm_select_http_incoming();
 		}
-		if (commCheckICPIncoming)
-		    comm_select_icp_incoming();
-		if (commCheckHTTPIncoming)
-		    comm_select_http_incoming();
-		EBIT_CLR(tmask, k);	/* this bit is done */
-		if (tmask == 0)
-		    break;	/* and no more bits left */
 	    }
 	}
 	if (callicp)
 	    comm_select_icp_incoming();
+	if (calldns)
+	    comm_select_dns_incoming();
 	if (callhttp)
 	    comm_select_http_incoming();
+#if DELAY_POOLS
+	while ((fd = commGetSlowFd()) != -1) {
+	    F = &fd_table[fd];
+	    debug(5, 6) ("comm_select: slow FD %d selected for reading\n", fd);
+	    if ((hdl = F->read_handler)) {
+		F->read_handler = NULL;
+		commUpdateReadBits(fd, NULL);
+		hdl(fd, F->read_data);
+		Counter.select_fds++;
+		if (commCheckICPIncoming)
+		    comm_select_icp_incoming();
+		if (commCheckDNSIncoming)
+		    comm_select_dns_incoming();
+		if (commCheckHTTPIncoming)
+		    comm_select_http_incoming();
+	    }
+	}
+#endif
 	return COMM_OK;
-    } while (timeout > current_dtime);
+    }
+    while (timeout > current_dtime);
     debug(5, 8) ("comm_select: time out: %d\n", (int) squid_curtime);
     return COMM_TIMEOUT;
 }
 #endif
 
+static void
+#if HAVE_POLL
+comm_poll_dns_incoming(void)
+#else
+comm_select_dns_incoming(void)
+#endif
+{
+    int nfds = 0;
+    int fds[2];
+    int nevents;
+    dns_io_events = 0;
+    if (DnsSocket < 0)
+	return;
+    fds[nfds++] = DnsSocket;
+#if HAVE_POLL
+    nevents = comm_check_incoming_poll_handlers(nfds, fds);
+#else
+    nevents = comm_check_incoming_select_handlers(nfds, fds);
+#endif
+    if (nevents < 0)
+	return;
+    incoming_dns_interval += Config.comm_incoming.dns_average - nevents;
+    if (incoming_dns_interval < Config.comm_incoming.dns_min_poll)
+	incoming_dns_interval = Config.comm_incoming.dns_min_poll;
+    if (incoming_dns_interval > MAX_INCOMING_INTERVAL)
+	incoming_dns_interval = MAX_INCOMING_INTERVAL;
+    if (nevents > INCOMING_DNS_MAX)
+	nevents = INCOMING_DNS_MAX;
+    statHistCount(&Counter.comm_dns_incoming, nevents);
+}
+
 void
 comm_select_init(void)
 {
@@ -839,6 +1033,8 @@
     StatCounters *f = &Counter;
     storeAppendPrintf(sentry, "Current incoming_icp_interval: %d\n",
 	incoming_icp_interval >> INCOMING_FACTOR);
+    storeAppendPrintf(sentry, "Current incoming_dns_interval: %d\n",
+	incoming_dns_interval >> INCOMING_FACTOR);
     storeAppendPrintf(sentry, "Current incoming_http_interval: %d\n",
 	incoming_http_interval >> INCOMING_FACTOR);
     storeAppendPrintf(sentry, "\n");
@@ -850,6 +1046,12 @@
 #endif
     statHistDump(&f->comm_icp_incoming, sentry, statHistIntDumper);
 #ifdef HAVE_POLL
+    storeAppendPrintf(sentry, "DNS Messages handled per comm_poll_dns_incoming() call:\n");
+#else
+    storeAppendPrintf(sentry, "DNS Messages handled per comm_select_dns_incoming() call:\n");
+#endif
+    statHistDump(&f->comm_dns_incoming, sentry, statHistIntDumper);
+#ifdef HAVE_POLL
     storeAppendPrintf(sentry, "HTTP Messages handled per comm_poll_http_incoming() call:\n");
 #else
     storeAppendPrintf(sentry, "HTTP Messages handled per comm_select_http_incoming() call:\n");
Index: squid/src/debug.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/debug.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/debug.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/debug.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: debug.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: debug.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -202,6 +202,11 @@
 	    return;
 #endif
 
+    /*
+     * NOTE: we cannot use xrename here without having it in a
+     * separate file -- tools.c has too many dependencies to be
+     * used everywhere debug.c is used.
+     */
     /* Rotate numbers 0 through N up one */
     for (i = Config.Log.rotateNumber; i > 1;) {
 	i--;
@@ -365,7 +370,7 @@
  * info for deducing the current execution stack
  */
 static void
-ctx_print()
+ctx_print(void)
 {
     /* lock so _db_print will not call us recursively */
     Ctx_Lock++;
Index: squid/src/defines.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/defines.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/defines.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/defines.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: defines.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: defines.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -205,10 +205,6 @@
 
 #define STORE_ENTRY_WITH_MEMOBJ		1
 #define STORE_ENTRY_WITHOUT_MEMOBJ	0
-#define STORE_SWAP_BUF		DISK_PAGE_SIZE
-#define VM_WINDOW_SZ		DISK_PAGE_SIZE
-
-#define SKIP_BASIC_SZ ((size_t) 6)
 
 #define PINGER_PAYLOAD_SZ 8192
 
@@ -246,6 +242,10 @@
  */
 #define INCOMING_ICP_MAX 15
 /*
+ * Max number of DNS messages to receive per call to DNS read handler
+ */
+#define INCOMING_DNS_MAX 15
+/*
  * Max number of HTTP connections to accept per call to httpAccept
  * and PER HTTP PORT
  */
@@ -260,13 +260,18 @@
 
 #define CLIENT_SOCK_SZ 4096
 
-#define URI_WHITESPACE_DENY 0
+#define URI_WHITESPACE_STRIP 0
 #define URI_WHITESPACE_ALLOW 1
 #define URI_WHITESPACE_ENCODE 2
 #define URI_WHITESPACE_CHOP 3
+#define URI_WHITESPACE_DENY 4
 
 #ifndef _PATH_DEVNULL
 #define _PATH_DEVNULL "/dev/null"
 #endif
 
-#define USE_TRUNCATE_NOT_UNLINK 1
+#if USE_ASYNC_IO
+#ifndef NUMTHREADS
+#define NUMTHREADS 16
+#endif
+#endif
Index: squid/src/delay_pools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/delay_pools.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/delay_pools.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/delay_pools.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: delay_pools.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: delay_pools.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 77    Delay Pools
  * AUTHOR: David Luyer <luyer@ucs.uwa.edu.au>
@@ -149,7 +149,7 @@
 }
 
 void
-delayFreeDelayData()
+delayFreeDelayData(void)
 {
     safe_free(delay_data);
     if (!delay_id_ptr_hash)
@@ -283,6 +283,7 @@
     memset(&ch, '\0', sizeof(ch));
     ch.src_addr = r->client_addr;
     ch.my_addr = r->my_addr;
+    ch.my_port = r->my_port;
     ch.request = r;
     for (pool = 0; pool < Config.Delay.pools; pool++) {
 	if (aclCheckFast(Config.Delay.access[pool], &ch))
Index: squid/src/disk.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/disk.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/disk.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/disk.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,6 @@
 
-
 /*
- * $Id: disk.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: disk.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 6     Disk I/O Routines
  * AUTHOR: Harvest Derived
@@ -36,113 +35,61 @@
 
 #include "squid.h"
 
-#define DISK_LINE_LEN  1024
-
-typedef struct open_ctrl_t {
-    FOCB *callback;
-    void *callback_data;
-    char *path;
-} open_ctrl_t;
-
-static AIOCB diskHandleWriteComplete;
-static AIOCB diskHandleReadComplete;
 static PF diskHandleRead;
 static PF diskHandleWrite;
-static AIOCB fileOpenComplete;
+
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_OS2_)
+static int
+diskWriteIsComplete(int fd)
+{
+    return fd_table[fd].disk.write_q ? 0 : 1;
+}
+#endif
 
 void
 disk_init(void)
 {
-#if USE_ASYNC_IO
-    aioClose(dup(0));
-#endif
+    (void) 0;
 }
 
-/* Open a disk file. Return a file descriptor */
+/*
+ * opens a disk file specified by 'path'.  This function always
+ * blocks!  There is no callback.
+ */
 int
-file_open(const char *path, int mode, FOCB * callback, void *callback_data, void *tag)
+file_open(const char *path, int mode)
 {
     int fd;
-    open_ctrl_t *ctrlp;
-
-    ctrlp = xmalloc(sizeof(open_ctrl_t));
-    ctrlp->path = xstrdup(path);
-    ctrlp->callback = callback;
-    ctrlp->callback_data = callback_data;
-
     if (mode & O_WRONLY)
 	mode |= O_APPEND;
     mode |= SQUID_NONBLOCK;
-
-    /* Open file */
-    Opening_FD++;
-#if USE_ASYNC_IO
-    if (callback != NULL) {
-	aioOpen(path, mode, 0644, fileOpenComplete, ctrlp, tag);
-	return DISK_OK;
-    }
-#endif
     errno = 0;
     fd = open(path, mode, 0644);
-    fileOpenComplete(-1, ctrlp, fd, errno);
-    if (fd < 0)
-	return DISK_ERROR;
-    return fd;
-}
-
-
-static void
-fileOpenComplete(int unused, void *data, int fd, int errcode)
-{
-    open_ctrl_t *ctrlp = (open_ctrl_t *) data;
-    debug(6, 5) ("fileOpenComplete: FD %d, data %p, errcode %d\n",
-	fd, data, errcode);
     Counter.syscalls.disk.opens++;
-    Opening_FD--;
-    if (fd == -2 && errcode == -2) {	/* Cancelled - clean up */
-	if (ctrlp->callback)
-	    (ctrlp->callback) (ctrlp->callback_data, fd, errcode);
-	xfree(ctrlp->path);
-	xfree(ctrlp);
-	return;
-    }
     if (fd < 0) {
-	errno = errcode;
-	debug(50, 3) ("fileOpenComplete: error opening file %s: %s\n", ctrlp->path,
+	debug(50, 3) ("file_open: error opening file %s: %s\n", path,
 	    xstrerror());
-	if (ctrlp->callback)
-	    (ctrlp->callback) (ctrlp->callback_data, DISK_ERROR, errcode);
-	xfree(ctrlp->path);
-	xfree(ctrlp);
-	return;
+	fd = DISK_ERROR;
+    } else {
+	debug(6, 5) ("file_open: FD %d\n", fd);
+	commSetCloseOnExec(fd);
+	fd_open(fd, FD_FILE, path);
     }
-    debug(6, 5) ("fileOpenComplete: FD %d\n", fd);
-    commSetCloseOnExec(fd);
-    fd_open(fd, FD_FILE, ctrlp->path);
-    if (ctrlp->callback)
-	(ctrlp->callback) (ctrlp->callback_data, fd, errcode);
-    xfree(ctrlp->path);
-    xfree(ctrlp);
+    return fd;
 }
 
+
 /* close a disk file. */
 void
 file_close(int fd)
 {
     fde *F = &fd_table[fd];
-    PF *callback;
-#if USE_ASYNC_IO
-    if (fd < 0) {
-	debug(6, 0) ("file_close: FD less than zero: %d\n", fd);
-	return;
-    }
-#else
+    PF *read_callback;
     assert(fd >= 0);
-#endif
     assert(F->flags.open);
-    if ((callback = F->read_handler)) {
+    if ((read_callback = F->read_handler)) {
 	F->read_handler = NULL;
-	callback(-1, F->read_data);
+	read_callback(-1, F->read_data);
     }
     if (F->flags.write_daemon) {
 #if defined(_SQUID_MSWIN_) || defined(_SQUID_OS2_)
@@ -164,19 +111,13 @@
      */
     assert(F->write_handler == NULL);
     F->flags.closing = 1;
-#if USE_ASYNC_IO
-    aioClose(fd);
-#else
 #if CALL_FSYNC_BEFORE_CLOSE
     fsync(fd);
 #endif
     close(fd);
-#endif
     debug(6, F->flags.close_request ? 2 : 5)
 	("file_close: FD %d, really closing\n", fd);
-#if !USE_ASYNC_IO
     fd_close(fd);
-#endif
     Counter.syscalls.disk.closes++;
 }
 
@@ -230,83 +171,27 @@
 static void
 diskHandleWrite(int fd, void *notused)
 {
-#if !USE_ASYNC_IO
     int len = 0;
-#endif
     fde *F = &fd_table[fd];
     struct _fde_disk *fdd = &F->disk;
-    if (!fdd->write_q)
+    dwrite_q *q = fdd->write_q;
+    int status = DISK_OK;
+    int do_callback;
+    int do_close;
+    if (NULL == q)
 	return;
-#ifdef OPTIMISTIC_IO
-    assert(!F->flags.calling_io_handler);
-#endif
     debug(6, 3) ("diskHandleWrite: FD %d\n", fd);
+    F->flags.write_daemon = 0;
     assert(fdd->write_q != NULL);
     assert(fdd->write_q->len > fdd->write_q->buf_offset);
-#if USE_ASYNC_IO
-    aioWrite(fd,
-	-1,			/* seek offset, -1 == append */
-	fdd->write_q->buf + fdd->write_q->buf_offset,
-	fdd->write_q->len - fdd->write_q->buf_offset,
-	diskHandleWriteComplete,
-	fdd->write_q);
-#else
     debug(6, 3) ("diskHandleWrite: FD %d writing %d bytes\n",
 	fd, (int) (fdd->write_q->len - fdd->write_q->buf_offset));
     errno = 0;
     len = write(fd,
 	fdd->write_q->buf + fdd->write_q->buf_offset,
 	fdd->write_q->len - fdd->write_q->buf_offset);
-    diskHandleWriteComplete(fd, fdd->write_q, len, errno);
-#endif
-}
-
-static void
-diskHandleWriteComplete(int fd, void *data, int len, int errcode)
-{
-    fde *F = &fd_table[fd];
-    struct _fde_disk *fdd = &F->disk;
-    dwrite_q *q = fdd->write_q;
-    int status = DISK_OK;
-    int do_callback;
-    int do_close;
-    errno = errcode;
-    debug(6, 3) ("diskHandleWriteComplete: FD %d len = %d\n", fd, len);
+    debug(6, 3) ("diskHandleWrite: FD %d len = %d\n", fd, len);
     Counter.syscalls.disk.writes++;
-#if USE_ASYNC_IO
-/*
- * From:    "Michael O'Reilly" <michael@metal.iinet.net.au>
- * Date:    24 Feb 1998 15:12:06 +0800
- *
- * A small patch to improve the AIO sanity. the patch below makes sure
- * the write request really does match the data passed back from the
- * async IO call.  note that I haven't actually rebooted with this
- * patch yet, so 'provisional' is an understatement.
- */
-    if (q && q != data) {
-	dwrite_q *p = data;
-	debug(50, 0) ("KARMA: q != data (%p, %p)\n", q, p);
-	debug(50, 0) ("KARMA: (%d, %d, %d FD %d)\n",
-	    q->buf_offset, q->len, len, fd);
-	debug(50, 0) ("KARMA: desc %s, type %d, open %d, flags 0x%x\n",
-	    F->desc, F->type, F->flags.open, F->flags);
-	debug(50, 0) ("KARMA: (%d, %d)\n", p->buf_offset, p->len);
-	len = -1;
-	errcode = EFAULT;
-    }
-#endif
-    if (q == NULL)		/* Someone aborted then write completed */
-	return;
-
-    if (len == -2 && errcode == -2) {	/* Write cancelled - cleanup */
-	do {
-	    fdd->write_q = q->next;
-	    if (q->free_func)
-		(q->free_func) (q->buf);
-	    safe_free(q);
-	} while ((q = fdd->write_q));
-	return;
-    }
     fd_bytes(fd, len, FD_WRITE);
     if (len < 0) {
 	if (!ignoreErrno(errno)) {
@@ -360,7 +245,6 @@
     if (fdd->write_q == NULL) {
 	/* no more data */
 	fdd->write_q_tail = NULL;
-	F->flags.write_daemon = 0;
     } else {
 	/* another block is queued */
 	diskCombineWrites(fdd);
@@ -379,17 +263,11 @@
 	if (fdd->wrt_handle_data != NULL)
 	    cbdataUnlock(fdd->wrt_handle_data);
 	if (do_callback) {
-#ifdef OPTIMISTIC_IO
-	    F->flags.calling_io_handler = 1;
-#endif
 	    fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data);
 	    /*
 	     * NOTE, this callback can close the FD, so we must
 	     * not touch 'F', 'fdd', etc. after this.
 	     */
-#ifdef OPTIMISTIC_IO
-	    F->flags.calling_io_handler = 0;
-#endif
 	    return;
 	}
     }
@@ -434,21 +312,7 @@
     }
     if (!F->flags.write_daemon) {
 	cbdataLock(F->disk.wrt_handle_data);
-#if USE_ASYNC_IO
 	diskHandleWrite(fd, NULL);
-#else
-#ifdef OPTIMISTIC_IO
-	if (F->flags.calling_io_handler)
-#endif
-	    commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0);
-#ifdef OPTIMISTIC_IO
-	else
-	    diskHandleWrite(fd, NULL);
-#endif
-#endif
-#ifndef OPTIMISTIC_IO
-	F->flags.write_daemon = 1;
-#endif
     }
 }
 
@@ -467,13 +331,9 @@
 diskHandleRead(int fd, void *data)
 {
     dread_ctrl *ctrl_dat = data;
-#if !USE_ASYNC_IO
     fde *F = &fd_table[fd];
     int len;
-#endif
-#ifdef OPTIMISTIC_IO
-    assert(!F->flags.calling_io_handler);
-#endif /* OPTIMISTIC_IO */
+    int rc = DISK_OK;
     /*
      * FD < 0 indicates premature close; we just have to free
      * the state data.
@@ -482,14 +342,6 @@
 	memFree(ctrl_dat, MEM_DREAD_CTRL);
 	return;
     }
-#if USE_ASYNC_IO
-    aioRead(fd,
-	ctrl_dat->offset,
-	ctrl_dat->buf,
-	ctrl_dat->req_len,
-	diskHandleReadComplete,
-	ctrl_dat);
-#else
     if (F->disk.offset != ctrl_dat->offset) {
 	debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n",
 	    fd, (int) ctrl_dat->offset);
@@ -501,25 +353,7 @@
     len = read(fd, ctrl_dat->buf, ctrl_dat->req_len);
     if (len > 0)
 	F->disk.offset += len;
-    diskHandleReadComplete(fd, ctrl_dat, len, errno);
-#endif
-}
-
-static void
-diskHandleReadComplete(int fd, void *data, int len, int errcode)
-{
-    dread_ctrl *ctrl_dat = data;
-    int rc = DISK_OK;
-#ifdef OPTIMISTIC_IO
-    fde *F = &fd_table[fd];
-#endif /* OPTIMISTIC_IO */
     Counter.syscalls.disk.reads++;
-    errno = errcode;
-    if (len == -2 && errcode == -2) {	/* Read cancelled - cleanup */
-	cbdataUnlock(ctrl_dat->client_data);
-	memFree(ctrl_dat, MEM_DREAD_CTRL);
-	return;
-    }
     fd_bytes(fd, len, FD_READ);
     if (len < 0) {
 	if (ignoreErrno(errno)) {
@@ -532,14 +366,8 @@
     } else if (len == 0) {
 	rc = DISK_EOF;
     }
-#ifdef OPTIMISTIC_IO
-    F->flags.calling_io_handler = 1;
-#endif /* OPTIMISTIC_IO */
     if (cbdataValid(ctrl_dat->client_data))
 	ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data);
-#ifdef OPTIMISTIC_IO
-    F->flags.calling_io_handler = 0;
-#endif /* OPTIMISTIC_IO */
     cbdataUnlock(ctrl_dat->client_data);
     memFree(ctrl_dat, MEM_DREAD_CTRL);
 }
@@ -549,13 +377,10 @@
 /* buffer must be allocated from the caller. 
  * It must have at least req_len space in there. 
  * call handler when a reading is complete. */
-int
+void
 file_read(int fd, char *buf, int req_len, off_t offset, DRCB * handler, void *client_data)
 {
     dread_ctrl *ctrl_dat;
-#ifdef OPTIMISTIC_IO
-    fde *F = &fd_table[fd];
-#endif /* OPTIMISTIC_IO */
     assert(fd >= 0);
     ctrl_dat = memAllocate(MEM_DREAD_CTRL);
     ctrl_dat->fd = fd;
@@ -566,27 +391,5 @@
     ctrl_dat->handler = handler;
     ctrl_dat->client_data = client_data;
     cbdataLock(client_data);
-#if USE_ASYNC_IO
     diskHandleRead(fd, ctrl_dat);
-#else
-#ifndef OPTIMISTIC_IO
-    commSetSelect(fd,
-	COMM_SELECT_READ,
-	diskHandleRead,
-	ctrl_dat,
-	0);
-#else
-    if (F->flags.calling_io_handler)
-	commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);
-    else
-	diskHandleRead(fd, ctrl_dat);
-#endif /* OPTIMISTIC_IO */
-#endif
-    return DISK_OK;
-}
-
-int
-diskWriteIsComplete(int fd)
-{
-    return fd_table[fd].disk.write_q ? 0 : 1;
 }
Index: squid/src/dns.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/dns.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/dns.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/dns.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: dns.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 34    Dnsserver interface
  * AUTHOR: Harvest Derived
@@ -37,6 +37,7 @@
 
 static helper *dnsservers = NULL;
 
+#if USE_DNSSERVERS
 static void
 dnsStats(StoreEntry * sentry)
 {
@@ -44,9 +45,12 @@
     helperStats(sentry, dnsservers);
 }
 
+#endif
+
 void
 dnsInit(void)
 {
+#if USE_DNSSERVERS
     static int init = 0;
     wordlist *w;
     if (!Config.Program.dnsserver)
@@ -68,8 +72,9 @@
 	cachemgrRegister("dns",
 	    "Dnsserver Statistics",
 	    dnsStats, 0, 1);
+	init = 1;
     }
-    init++;
+#endif
 }
 
 void
@@ -100,29 +105,30 @@
 variable_list *
 snmp_netDnsFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     debug(49, 5) ("snmp_netDnsFn: Processing request:\n", Var->name[LEN_SQ_NET +
 	    1]);
     snmpDebugOid(5, Var->name, Var->name_length);
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-    Answer->val_len = sizeof(snint);
-    Answer->val.integer = xmalloc(Answer->val_len);
-    Answer->type = SMI_COUNTER32;
     switch (Var->name[LEN_SQ_NET + 1]) {
     case DNS_REQ:
-	*(Answer->val.integer) = dnsservers->stats.requests;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    dnsservers->stats.requests,
+	    SMI_COUNTER32);
 	break;
     case DNS_REP:
-	*(Answer->val.integer) = dnsservers->stats.replies;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    dnsservers->stats.replies,
+	    SMI_COUNTER32);
 	break;
     case DNS_SERVERS:
-	*(Answer->val.integer) = dnsservers->n_running;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    dnsservers->n_running,
+	    SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
Index: squid/src/dns_internal.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/dns_internal.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/src/dns_internal.c	26 Jan 2000 03:25:01 -0000	1.1
+++ squid/src/dns_internal.c	26 Jan 2000 03:25:01 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.c,v 1.1 2000/01/26 03:25:01 hno Exp $
+ * $Id: dns_internal.c,v 1.1.1.1 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
Index: squid/src/dnsserver.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/dnsserver.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/dnsserver.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/dnsserver.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dnsserver.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: dnsserver.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 0     DNS Resolver
  * AUTHOR: Harvest Derived
@@ -266,6 +266,9 @@
 
 #if HAVE_RES_INIT
     res_init();
+#ifdef RES_DEFAULT
+    _res.options = RES_DEFAULT;
+#endif
 #ifdef RES_DEFNAMES
     _res.options &= ~RES_DEFNAMES;
 #endif
Index: squid/src/enums.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/enums.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/enums.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/enums.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: enums.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -85,6 +85,7 @@
     ERR_FTP_FORBIDDEN,
     ERR_FTP_UNAVAILABLE,
     ERR_ONLY_IF_CACHED_MISS,	/* failure to satisfy only-if-cached request */
+    ERR_TOO_BIG,
     ERR_MAX
 } err_type;
 
@@ -101,6 +102,7 @@
     ACL_URLPATH_REGEX,
     ACL_URL_REGEX,
     ACL_URL_PORT,
+    ACL_MY_PORT,
 #if USE_IDENT
     ACL_IDENT,
 #endif
@@ -113,6 +115,7 @@
     ACL_SRC_ARP,
     ACL_SNMP_COMMUNITY,
     ACL_NETDB_SRC_RTT,
+    ACL_MAXCONN,
     ACL_ENUM_MAX
 } squid_acl;
 
@@ -245,6 +248,7 @@
     CC_MUST_REVALIDATE,
     CC_PROXY_REVALIDATE,
     CC_MAX_AGE,
+    CC_S_MAXAGE,
     CC_ONLY_IF_CACHED,
     CC_OTHER,
     CC_ENUM_END
@@ -289,7 +293,8 @@
     SOURCE_FASTEST,
     ROUNDROBIN_PARENT,
 #if USE_CACHE_DIGESTS
-    CACHE_DIGEST_HIT,
+    CD_PARENT_HIT,
+    CD_SIBLING_HIT,
 #endif
 #if USE_CARP
     CARP,
@@ -311,9 +316,9 @@
     ICP_DATAEND,
     ICP_SECHO,
     ICP_DECHO,
-    ICP_UNUSED12,
-    ICP_UNUSED13,
-    ICP_UNUSED14,
+    ICP_NOTIFY,
+    ICP_INVALIDATE,
+    ICP_DELETE,
     ICP_UNUSED15,
     ICP_UNUSED16,
     ICP_UNUSED17,
@@ -344,7 +349,6 @@
 
 enum {
     SWAPOUT_NONE,
-    SWAPOUT_OPENING,
     SWAPOUT_WRITING,
     SWAPOUT_DONE
 };
@@ -364,6 +368,15 @@
     METHOD_CONNECT,		/* 101 */
     METHOD_TRACE,		/* 110 */
     METHOD_PURGE,		/* 111 */
+    METHOD_OPTIONS,
+    METHOD_DELETE,		/* RFC2616 section 9.7 */
+    METHOD_PROPFIND,
+    METHOD_PROPPATCH,
+    METHOD_MKCOL,
+    METHOD_COPY,
+    METHOD_MOVE,
+    METHOD_LOCK,
+    METHOD_UNLOCK,
     METHOD_ENUM_END
 };
 typedef unsigned int method_t;
@@ -390,6 +403,7 @@
     HTTP_STATUS_NONE = 0,
     HTTP_CONTINUE = 100,
     HTTP_SWITCHING_PROTOCOLS = 101,
+    HTTP_PROCESSING = 102,	/* RFC2518 section 10.1 */
     HTTP_OK = 200,
     HTTP_CREATED = 201,
     HTTP_ACCEPTED = 202,
@@ -397,6 +411,7 @@
     HTTP_NO_CONTENT = 204,
     HTTP_RESET_CONTENT = 205,
     HTTP_PARTIAL_CONTENT = 206,
+    HTTP_MULTI_STATUS = 207,	/* RFC2518 section 10.2 */
     HTTP_MULTIPLE_CHOICES = 300,
     HTTP_MOVED_PERMANENTLY = 301,
     HTTP_MOVED_TEMPORARILY = 302,
@@ -419,12 +434,16 @@
     HTTP_REQUEST_ENTITY_TOO_LARGE = 413,
     HTTP_REQUEST_URI_TOO_LARGE = 414,
     HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
+    HTTP_UNPROCESSABLE_ENTITY = 422,	/* RFC2518 section 10.3 */
+    HTTP_LOCKED = 423,		/* RFC2518 section 10.4 */
+    HTTP_FAILED_DEPENDENCY = 424,	/* RFC2518 section 10.5 */
     HTTP_INTERNAL_SERVER_ERROR = 500,
     HTTP_NOT_IMPLEMENTED = 501,
     HTTP_BAD_GATEWAY = 502,
     HTTP_SERVICE_UNAVAILABLE = 503,
     HTTP_GATEWAY_TIMEOUT = 504,
     HTTP_HTTP_VERSION_NOT_SUPPORTED = 505,
+    HTTP_INSUFFICIENT_STORAGE = 507,	/* RFC2518 section 10.6 */
     HTTP_INVALID_HEADER = 600	/* Squid header parsing error */
 } http_status;
 
@@ -447,7 +466,8 @@
     ENTRY_NEGCACHED,
     ENTRY_VALIDATED,
     ENTRY_BAD_LENGTH,
-    ENTRY_ABORTED
+    ENTRY_ABORTED,
+    ENTRY_DONT_LOG		/* hack for gross 'Pump' entries */
 };
 
 typedef enum {
@@ -516,6 +536,10 @@
     MEM_HELPER_REQUEST,
     MEM_HELPER_SERVER,
     MEM_HIERARCHYLOGENTRY,
+#if USE_HTCP
+    MEM_HTCP_SPECIFIER,
+    MEM_HTCP_DETAIL,
+#endif
     MEM_HTTP_HDR_CC,
     MEM_HTTP_HDR_CONTENT_RANGE,
     MEM_HTTP_HDR_ENTRY,
@@ -555,6 +579,11 @@
     MEM_SWAPDIR,
     MEM_USHORTLIST,
     MEM_WORDLIST,
+    MEM_STORE_IO,
+#if !USE_DNSSERVERS
+    MEM_IDNS_QUERY,
+#endif
+    MEM_EVENT,
     MEM_MAX
 } mem_type;
 
@@ -622,3 +651,9 @@
     NETDB_EX_RTT,
     NETDB_EX_HOPS
 };
+
+typedef enum {
+    SWAPDIR_UFS,
+    SWAPDIR_ASYNCUFS,
+    SWAPDIR_MAX
+} swapdir_t;
Index: squid/src/errorpage.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/errorpage.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/errorpage.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/errorpage.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: errorpage.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 4     Error Generation
  * AUTHOR: Duane Wessels
@@ -67,7 +67,7 @@
 	ERR_SQUID_SIGNATURE,
 	    "\n<br clear=\"all\">\n"
 	    "<hr noshade size=1>\n"
-	    "Generated %T by %h (<a href=\"http://squid.nlanr.net/Squid/\">%s</a>)\n"
+	    "Generated %T by %h (%s)\n"
 	    "</BODY></HTML>\n"
     }
 };
@@ -171,7 +171,7 @@
     char *text;
 
     snprintf(path, sizeof(path), "%s/%s", dir, page_name);
-    fd = file_open(path, O_RDONLY, NULL, NULL, NULL);
+    fd = file_open(path, O_RDONLY);
     if (fd < 0 || fstat(fd, &sb) < 0) {
 	debug(4, 0) ("errorTryLoadText: '%s': %s\n", path, xstrerror());
 	if (fd >= 0)
@@ -378,6 +378,9 @@
     safe_free(err->host);
     safe_free(err->dnsserver_msg);
     safe_free(err->request_hdrs);
+    wordlistDestroy(&err->ftp.server_msg);
+    safe_free(err->ftp.request);
+    safe_free(err->ftp.reply);
     if (err->flags.flag_cbdata)
 	cbdataFree(err);
     else
@@ -451,7 +454,7 @@
 	break;
     case 'g':
 	/* FTP SERVER MESSAGE */
-	wordlistCat(err->ftp_server_msg, &mb);
+	wordlistCat(err->ftp.server_msg, &mb);
 	break;
     case 'h':
 	memBufPrintf(&mb, "%s", getMyHostname());
Index: squid/src/event.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/event.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/event.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/event.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: event.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: event.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 41    Event Processing
  * AUTHOR: Henrik Nordstrom
@@ -49,11 +49,12 @@
 static struct ev_entry *tasks = NULL;
 static OBJH eventDump;
 static int run_id = 0;
+static const char *last_event_ran = NULL;
 
 void
 eventAdd(const char *name, EVH * func, void *arg, double when, int weight)
 {
-    struct ev_entry *event = xcalloc(1, sizeof(struct ev_entry));
+    struct ev_entry *event = memAllocate(MEM_EVENT);
     struct ev_entry **E;
     event->func = func;
     event->arg = arg;
@@ -101,7 +102,7 @@
 	*E = event->next;
 	if (NULL != event->arg)
 	    cbdataUnlock(event->arg);
-	xfree(event);
+	memFree(event, MEM_EVENT);
 	return;
     }
     debug_trap("eventDelete: event not found");
@@ -121,6 +122,7 @@
     run_id++;
     debug(41, 5) ("eventRun: RUN ID %d\n", run_id);
     while ((event = tasks)) {
+	int valid = 1;
 	if (event->when > current_dtime)
 	    break;
 	if (event->id == run_id)	/* was added during this run */
@@ -133,17 +135,18 @@
 	event->arg = NULL;
 	tasks = event->next;
 	if (NULL != arg) {
-	    int valid = cbdataValid(arg);
+	    valid = cbdataValid(arg);
 	    cbdataUnlock(arg);
-	    if (!valid) {
-		safe_free(event);
-		return;
-	    }
 	}
-	weight += event->weight;
-	debug(41, 5) ("eventRun: Running '%s', id %d\n", event->name, event->id);
-	func(arg);
-	safe_free(event);
+	if (valid) {
+	    weight += event->weight;
+	    /* XXX assumes ->name is static memory! */
+	    last_event_ran = event->name;
+	    debug(41, 5) ("eventRun: Running '%s', id %d\n",
+		event->name, event->id);
+	    func(arg);
+	}
+	memFree(event, MEM_EVENT);
     }
 }
 
@@ -158,6 +161,7 @@
 void
 eventInit(void)
 {
+    memDataInit(MEM_EVENT, "event", sizeof(struct ev_entry), 0);
     cachemgrRegister("events",
 	"Event Queue",
 	eventDump, 0, 1);
@@ -167,12 +171,17 @@
 eventDump(StoreEntry * sentry)
 {
     struct ev_entry *e = tasks;
-    storeAppendPrintf(sentry, "%s\t%s\n",
+    if (last_event_ran)
+	storeAppendPrintf(sentry, "Last event to run: %s\n\n", last_event_ran);
+    storeAppendPrintf(sentry, "%s\t%s\t%s\t%s\n",
 	"Operation",
-	"Next Execution");
+	"Next Execution",
+	"Weight",
+	"Callback Valid?");
     while (e != NULL) {
-	storeAppendPrintf(sentry, "%s\t%f seconds\n",
-	    e->name, e->when - current_dtime);
+	storeAppendPrintf(sentry, "%s\t%f seconds\t%d\t%s\n",
+	    e->name, e->when - current_dtime, e->weight,
+	    e->arg ? cbdataValid(e->arg) ? "yes" : "no" : "N/A");
 	e = e->next;
     }
 }
@@ -184,7 +193,7 @@
     while ((event = tasks)) {
 	if (NULL != event->arg)
 	    cbdataUnlock(event->arg);
-	xfree(event);
+	memFree(event, MEM_EVENT);
     }
     tasks = NULL;
 }
Index: squid/src/fd.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fd.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/fd.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/fd.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: fd.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: fd.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 51    Filedescriptor Functions
  * AUTHOR: Duane Wessels
@@ -90,16 +90,6 @@
     F->timeout = 0;
 }
 
-#if USE_ASYNC_IO
-void
-fd_was_closed(int fd)
-{
-    fde *F = &fd_table[fd];
-    if (F->flags.closing)
-	fd_close(fd);
-}
-#endif
-
 void
 fd_open(int fd, unsigned int type, const char *desc)
 {
Index: squid/src/filemap.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/filemap.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/src/filemap.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/src/filemap.c	26 Jan 2000 03:25:01 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: filemap.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: filemap.c,v 1.1.1.2 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 8     Swap File Bitmap
  * AUTHOR: Harvest Derived
@@ -53,35 +53,47 @@
 #define ALL_ONES (unsigned long) 0xFFFFFFFF
 #endif
 
+#define FM_INITIAL_NUMBER (1<<14)
+
 fileMap *
-file_map_create(int n)
+file_map_create(void)
 {
     fileMap *fm = xcalloc(1, sizeof(fileMap));
-    fm->max_n_files = n;
-    fm->nwords = n >> LONG_BIT_SHIFT;
-    debug(8, 3) ("file_map_create: creating space for %d files\n", n);
+    fm->max_n_files = FM_INITIAL_NUMBER;
+    fm->nwords = fm->max_n_files >> LONG_BIT_SHIFT;
+    debug(8, 3) ("file_map_create: creating space for %d files\n", fm->max_n_files);
     debug(8, 5) ("--> %d words of %d bytes each\n",
-	fm->nwords, sizeof(unsigned long));
-    fm->file_map = xcalloc(fm->nwords, sizeof(unsigned long));
+	fm->nwords, sizeof(*fm->file_map));
+    fm->file_map = xcalloc(fm->nwords, sizeof(*fm->file_map));
     /* XXX account fm->file_map */
     return fm;
 }
 
+static void
+file_map_grow(fileMap * fm)
+{
+    int old_sz = fm->nwords * sizeof(*fm->file_map);
+    void *old_map = fm->file_map;
+    fm->max_n_files <<= 1;
+    assert(fm->max_n_files <= (1 << 30));
+    fm->nwords = fm->max_n_files >> LONG_BIT_SHIFT;
+    debug(8, 3) ("file_map_grow: creating space for %d files\n", fm->max_n_files);
+    fm->file_map = xcalloc(fm->nwords, sizeof(*fm->file_map));
+    debug(8, 3) ("copying %d old bytes\n", old_sz);
+    xmemcpy(fm->file_map, old_map, old_sz);
+    xfree(old_map);
+    /* XXX account fm->file_map */
+}
+
 int
 file_map_bit_set(fileMap * fm, int file_number)
 {
     unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
+    while (file_number >= fm->max_n_files)
+	file_map_grow(fm);
     fm->file_map[file_number >> LONG_BIT_SHIFT] |= bitmask;
     fm->n_files_in_map++;
-    if (!fm->toggle && (fm->n_files_in_map > ((fm->max_n_files * 7) >> 3))) {
-	fm->toggle++;
-	debug(8, 0) ("WARNING: filemap utilization at %d%%\n"
-	    "\tConsider decreasing store_avg_object_size in squid.conf\n",
-	    percent(fm->n_files_in_map, fm->max_n_files));
-    } else if (fm->n_files_in_map == fm->max_n_files) {
-	fatal_dump("You've run out of swap file numbers.");
-    }
-    return (file_number);
+    return file_number;
 }
 
 void
@@ -96,6 +108,8 @@
 file_map_bit_test(fileMap * fm, int file_number)
 {
     unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
+    if (file_number >= fm->max_n_files)
+	return 0;
     /* be sure the return value is an int, not a u_long */
     return (fm->file_map[file_number >> LONG_BIT_SHIFT] & bitmask ? 1 : 0);
 }
@@ -106,7 +120,7 @@
     int word;
     int bit;
     int count;
-    if (suggestion > fm->max_n_files)
+    if (suggestion >= fm->max_n_files)
 	suggestion = 0;
     if (!file_map_bit_test(fm, suggestion)) {
 	return file_map_bit_set(fm, suggestion);
@@ -123,8 +137,9 @@
 	    return file_map_bit_set(fm, suggestion);
 	}
     }
-    fatal("file_map_allocate: Exceeded filemap limit");
-    return 0;			/* NOTREACHED */
+    debug(8, 3) ("growing from file_map_allocate\n");
+    file_map_grow(fm);
+    return file_map_allocate(fm, fm->max_n_files >> 1);
 }
 
 void
@@ -134,15 +149,6 @@
     safe_free(fm);
 }
 
-void
-filemapCopy(fileMap * old, fileMap * new)
-{
-    assert(old->max_n_files <= new->max_n_files);
-    assert(0 == new->n_files_in_map);
-    xmemcpy(new->file_map, old->file_map, old->nwords * sizeof(unsigned long));
-    new->n_files_in_map = old->n_files_in_map;
-}
-
 #ifdef TEST
 
 #define TEST_SIZE 1<<16
Index: squid/src/forward.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/forward.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/forward.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/forward.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: forward.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: forward.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 17    Request Forwarding
  * AUTHOR: Duane Wessels
@@ -112,7 +112,7 @@
 	return 0;
     if (fwdState->flags.dont_retry)
 	return 0;
-    if (pumpMethod(fwdState->request->method))
+    if (fwdState->request->content_length >= 0)
 	if (0 == pumpRestart(fwdState->request))
 	    return 0;
     return 1;
@@ -139,7 +139,7 @@
 	    fs->next = NULL;
 	}
 	/* use eventAdd to break potential call sequence loops */
-	eventAdd("fwdConnectStart", fwdConnectStart, fwdState, 0.0, 1);
+	eventAdd("fwdConnectStart", fwdConnectStart, fwdState, 0.0, 0);
     } else {
 	fwdStateFree(fwdState);
     }
@@ -217,15 +217,19 @@
     FwdServer *fs = fwdState->servers;
     const char *host;
     unsigned short port;
+    time_t ctimeout;
     assert(fs);
     assert(fwdState->server_fd == -1);
     debug(17, 3) ("fwdConnectStart: %s\n", url);
     if (fs->peer) {
 	host = fs->peer->host;
 	port = fs->peer->http_port;
+	ctimeout = fs->peer->connect_timeout > 0 ? fs->peer->connect_timeout
+	    : Config.Timeout.peer_connect;
     } else {
 	host = fwdState->request->host;
 	port = fwdState->request->port;
+	ctimeout = Config.Timeout.connect;
     }
     hierarchyNote(&fwdState->request->hier, fs->code, host);
     if ((fd = pconnPop(host, port)) >= 0) {
@@ -255,7 +259,7 @@
     fwdState->n_tries++;
     comm_add_close_handler(fd, fwdServerClosed, fwdState);
     commSetTimeout(fd,
-	Config.Timeout.connect,
+	ctimeout,
 	fwdConnectTimeout,
 	fwdState);
     commConnectStart(fd, host, port, fwdConnectDone, fwdState);
@@ -292,6 +296,7 @@
     peer *p;
     request_t *request = fwdState->request;
     StoreEntry *entry = fwdState->entry;
+    ErrorState *err;
     debug(17, 3) ("fwdDispatch: FD %d: Fetching '%s %s'\n",
 	fwdState->client_fd,
 	RequestMethodStr[request->method],
@@ -309,6 +314,7 @@
     assert(fwdState->server_fd > -1);
     if (fwdState->servers && (p = fwdState->servers->peer)) {
 	p->stats.fetches++;
+	fwdState->request->peer_login = p->login;
 	httpStart(fwdState);
     } else {
 	switch (request->protocol) {
@@ -335,7 +341,20 @@
 	default:
 	    debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n",
 		storeUrl(entry));
-	    fwdFail(fwdState, errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST));
+	    err = errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST);
+	    err->request = requestLink(request);
+	    fwdFail(fwdState, err);
+	    /*
+	     * Force a persistent connection to be closed because
+	     * some Netscape browsers have a bug that sends CONNECT
+	     * requests as GET's over persistent connections.
+	     */
+	    request->flags.proxy_keepalive = 0;
+	    /*
+	     * Set the dont_retry flag becuase this is not a
+	     * transient (network) error; its a bug.
+	     */
+	    fwdState->flags.dont_retry = 1;
 	    comm_close(fwdState->server_fd);
 	    break;
 	}
@@ -357,7 +376,7 @@
     }
     if (fwdState->n_tries > 9)
 	return 0;
-    if (pumpMethod(fwdState->request->method))
+    if (fwdState->request->content_length >= 0)
 	if (0 == pumpRestart(fwdState->request))
 	    return 0;
     assert(fs);
@@ -385,8 +404,7 @@
 }
 
 void
-fwdStart(int fd, StoreEntry * e, request_t * r, struct in_addr client_addr,
-    struct in_addr my_addr)
+fwdStart(int fd, StoreEntry * e, request_t * r)
 {
     FwdState *fwdState;
     aclCheck_t ch;
@@ -397,19 +415,20 @@
      * from peer_digest.c, asn.c, netdb.c, etc and should always
      * be allowed.  yuck, I know.
      */
-    if (client_addr.s_addr != no_addr.s_addr) {
+    if (r->client_addr.s_addr != no_addr.s_addr) {
 	/*      
 	 * Check if this host is allowed to fetch MISSES from us (miss_access)
 	 */
 	memset(&ch, '\0', sizeof(aclCheck_t));
-	ch.src_addr = client_addr;
-	ch.my_addr = my_addr;
+	ch.src_addr = r->client_addr;
+	ch.my_addr = r->my_addr;
+	ch.my_port = r->my_port;
 	ch.request = r;
 	answer = aclCheckFast(Config.accessList.miss, &ch);
 	if (answer == 0) {
 	    err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);
 	    err->request = requestLink(r);
-	    err->src_addr = client_addr;
+	    err->src_addr = r->client_addr;
 	    errorAppendEntry(e, err);
 	    return;
 	}
@@ -458,6 +477,7 @@
 {
     StoreEntry *e = data;
     MemObject *mem = e->mem_obj;
+    int rc = 0;
     if (mem == NULL)
 	return 0;
 #if DELAY_POOLS
@@ -465,13 +485,21 @@
 	(void) 0;
     else if (delayIsNoDelay(fd))
 	(void) 0;
-    else if (delayMostBytesWanted(mem, 1) == 0)
-	return 1;
+    else {
+	int i = delayMostBytesWanted(mem, INT_MAX);
+	if (0 == i)
+	    return 1;
+	/* was: rc = -(rc != INT_MAX); */
+	else if (INT_MAX == i)
+	    rc = 0;
+	else
+	    rc = -1;
+    }
 #endif
     if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT))
-	return 0;
+	return rc;
     if (mem->inmem_hi - storeLowestMemReaderOffset(e) < READ_AHEAD_GAP)
-	return 0;
+	return rc;
     return 1;
 }
 
@@ -491,7 +519,7 @@
 /*
  * Called when someone else calls StoreAbort() on this entry
  */
-void
+static void
 fwdAbort(void *data)
 {
     FwdState *fwdState = data;
Index: squid/src/fqdncache.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fqdncache.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/fqdncache.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/fqdncache.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: fqdncache.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: fqdncache.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 35    FQDN Cache
  * AUTHOR: Harvest Derived
@@ -52,8 +52,13 @@
 
 static dlink_list lru_list;
 
+#if USE_DNSSERVERS
 static HLPCB fqdncacheHandleReply;
 static fqdncache_entry *fqdncacheParse(const char *buf);
+#else
+static IDNSCB fqdncacheHandleReply;
+static fqdncache_entry *fqdncacheParse(rfc1035_rr *, int);
+#endif
 static void fqdncache_release(fqdncache_entry *);
 static fqdncache_entry *fqdncache_create(const char *name);
 static void fqdncache_call_pending(fqdncache_entry *);
@@ -220,8 +225,8 @@
     fqdncacheUnlockEntry(f);
 }
 
-
 static fqdncache_entry *
+#if USE_DNSSERVERS
 fqdncacheParse(const char *inbuf)
 {
     LOCAL_ARRAY(char, buf, DNS_INBUF_SZ);
@@ -271,9 +276,54 @@
     }
     return &f;
 }
+#else
+fqdncacheParse(rfc1035_rr * answers, int nr)
+{
+    static fqdncache_entry f;
+    int k;
+    int j;
+    int na = 0;
+    memset(&f, '\0', sizeof(f));
+    f.expires = squid_curtime;
+    f.status = FQDN_NEGATIVE_CACHED;
+    if (nr < 0) {
+	debug(35, 3) ("fqdncacheParse: Lookup failed (error %d)\n",
+	    rfc1035_errno);
+	assert(rfc1035_error_message);
+	f.error_message = xstrdup(rfc1035_error_message);
+	return &f;
+    }
+    if (nr == 0) {
+	debug(35, 3) ("fqdncacheParse: No DNS records\n");
+	f.error_message = xstrdup("No DNS records");
+	return &f;
+    }
+    debug(35, 3) ("fqdncacheParse: %d answers\n", nr);
+    assert(answers);
+    for (j = 0, k = 0; k < nr; k++) {
+	if (answers[k].type != RFC1035_TYPE_PTR)
+	    continue;
+	if (answers[k].class != RFC1035_CLASS_IN)
+	    continue;
+	na++;
+	f.status = FQDN_CACHED;
+	f.names[0] = xstrdup(answers[k].rdata);
+	f.name_count = 1;
+	f.expires = squid_curtime + answers[k].ttl;
+	return &f;
+    }
+    debug(35, 1) ("fqdncacheParse: No PTR record\n");
+    f.error_message = xstrdup("No PTR record");
+    return &f;
+}
+#endif
 
 static void
+#if USE_DNSSERVERS
 fqdncacheHandleReply(void *data, char *reply)
+#else
+fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na)
+#endif
 {
     int n;
     generic_cbdata *c = data;
@@ -286,7 +336,11 @@
     n = ++FqdncacheStats.replies;
     statHistCount(&Counter.dns.svc_time,
 	tvSubMsec(f->request_time, current_time));
+#if USE_DNSSERVERS
     x = fqdncacheParse(reply);
+#else
+    x = fqdncacheParse(answers, na);
+#endif
     assert(x);
     f->name_count = x->name_count;
     for (n = 0; n < (int) f->name_count; n++)
@@ -369,7 +423,11 @@
     cbdataAdd(c, cbdataXfree, 0);
     f->status = FQDN_DISPATCHED;
     fqdncacheLockEntry(f);	/* lock while FQDN_DISPATCHED */
+#if USE_DNSSERVERS
     dnsSubmit(f->name, fqdncacheHandleReply, c);
+#else
+    idnsPTRLookup(addr, fqdncacheHandleReply, c);
+#endif
 }
 
 /* initialize the fqdncache */
@@ -622,46 +680,50 @@
 variable_list *
 snmp_netFqdnFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
-
+    variable_list *Answer = NULL;
     debug(49, 5) ("snmp_netFqdnFn: Processing request:\n", Var->name[LEN_SQ_NET +
 	    1]);
     snmpDebugOid(5, Var->name, Var->name_length);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-    Answer->val_len = sizeof(snint);
-    Answer->val.integer = xmalloc(Answer->val_len);
-    Answer->type = SMI_COUNTER32;
-
     switch (Var->name[LEN_SQ_NET + 1]) {
     case FQDN_ENT:
-	*(Answer->val.integer) = memInUse(MEM_FQDNCACHE_ENTRY);
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    memInUse(MEM_FQDNCACHE_ENTRY),
+	    SMI_GAUGE32);
 	break;
     case FQDN_REQ:
-	*(Answer->val.integer) = FqdncacheStats.requests;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.requests,
+	    SMI_COUNTER32);
 	break;
     case FQDN_HITS:
-	*(Answer->val.integer) = FqdncacheStats.hits;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.hits,
+	    SMI_COUNTER32);
 	break;
     case FQDN_PENDHIT:
-	*(Answer->val.integer) = FqdncacheStats.pending_hits;
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.pending_hits,
+	    SMI_GAUGE32);
 	break;
     case FQDN_NEGHIT:
-	*(Answer->val.integer) = FqdncacheStats.negative_hits;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.negative_hits,
+	    SMI_COUNTER32);
 	break;
     case FQDN_MISS:
-	*(Answer->val.integer) = FqdncacheStats.misses;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.misses,
+	    SMI_COUNTER32);
 	break;
     case FQDN_GHBN:
-	*(Answer->val.integer) = FqdncacheStats.ghba_calls;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    FqdncacheStats.ghba_calls,
+	    SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
Index: squid/src/ftp.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/ftp.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/ftp.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ftp.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ftp.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: ftp.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 9     File Transfer Protocol (FTP)
  * AUTHOR: Harvest Derived
@@ -85,9 +85,11 @@
     request_t *request;
     char user[MAX_URL];
     char password[MAX_URL];
+    int password_url;
     char *reply_hdr;
     int reply_hdr_state;
     char *title_url;
+    char *base_href;
     int conn_att;
     int login_att;
     ftp_state_t state;
@@ -163,8 +165,11 @@
 static void ftpScheduleReadControlReply(FtpStateData *, int);
 static void ftpHandleControlReply(FtpStateData *);
 static char *ftpHtmlifyListEntry(char *line, FtpStateData * ftpState);
+static void ftpFailed(FtpStateData *, err_type);
+static void ftpFailedErrorMessage(FtpStateData *, err_type);
 
-/* State machine functions
+/*
+ * State machine functions
  * send == state transition
  * read == wait for response, and select next state transition
  * other == Transition logic
@@ -234,24 +239,24 @@
 
 FTPSM *FTP_SM_FUNCS[] =
 {
-    ftpReadWelcome,
-    ftpReadUser,
-    ftpReadPass,
-    ftpReadType,
-    ftpReadMdtm,
-    ftpReadSize,
-    ftpReadPort,
-    ftpReadPasv,
-    ftpReadCwd,
+    ftpReadWelcome,		/* BEGIN */
+    ftpReadUser,		/* SENT_USER */
+    ftpReadPass,		/* SENT_PASS */
+    ftpReadType,		/* SENT_TYPE */
+    ftpReadMdtm,		/* SENT_MDTM */
+    ftpReadSize,		/* SENT_SIZE */
+    ftpReadPort,		/* SENT_PORT */
+    ftpReadPasv,		/* SENT_PASV */
+    ftpReadCwd,			/* SENT_CWD */
     ftpReadList,		/* SENT_LIST */
     ftpReadList,		/* SENT_NLST */
-    ftpReadRest,
-    ftpReadRetr,
-    ftpReadStor,
-    ftpReadQuit,
-    ftpReadTransferDone,
-    ftpSendReply,
-    ftpReadMkdir
+    ftpReadRest,		/* SENT_REST */
+    ftpReadRetr,		/* SENT_RETR */
+    ftpReadStor,		/* SENT_STOR */
+    ftpReadQuit,		/* SENT_QUIT */
+    ftpReadTransferDone,	/* READING_DATA (RETR,LIST,NLST) */
+    ftpSendReply,		/* WRITING_DATA (STOR) */
+    ftpReadMkdir		/* SENT_MKDIR */
 };
 
 static void
@@ -294,6 +299,7 @@
     safe_free(ftpState->old_reply);
     safe_free(ftpState->old_filepath);
     safe_free(ftpState->title_url);
+    safe_free(ftpState->base_href);
     safe_free(ftpState->filepath);
     safe_free(ftpState->data.host);
     if (ftpState->data.fd > -1) {
@@ -313,6 +319,7 @@
 	xstrncpy(ftpState->password, s + 1, MAX_URL);
 	if (escaped)
 	    rfc1738_unescape(ftpState->password);
+	ftpState->password_url = 1;
     } else {
 	xstrncpy(ftpState->password, null_string, MAX_URL);
     }
@@ -330,18 +337,14 @@
     FtpStateData *ftpState = data;
     StoreEntry *entry = ftpState->entry;
     debug(9, 4) ("ftpTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
-    if (entry->store_status == STORE_PENDING) {
-	if (entry->mem_obj->inmem_hi == 0) {
-	    fwdFail(ftpState->fwd,
-		errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT));
-	}
-    }
-    if (ftpState->data.fd > -1) {
-	comm_close(ftpState->data.fd);
-	ftpState->data.fd = -1;
+    if (SENT_PASV == ftpState->state && fd == ftpState->data.fd) {
+	/* stupid ftp.netscape.com */
+	ftpState->fwd->flags.dont_retry = 0;
+	ftpState->fwd->flags.ftp_pasv_failed = 1;
+	debug(9, 1) ("ftpTimeout: timeout in SENT_PASV state\n");
     }
-    comm_close(ftpState->ctrl.fd);
-    /* don't modify ftpState here, it has been freed */
+    ftpFailed(ftpState, ERR_READ_TIMEOUT);
+    /* ftpFailed closes ctrl.fd and frees ftpState */
 }
 
 static void
@@ -361,7 +364,7 @@
     storeAppendPrintf(e, "</TITLE>\n");
     if (ftpState->flags.use_base)
 	storeAppendPrintf(e, "<BASE HREF=\"%s\">\n",
-	    ftpState->title_url);
+	    ftpState->base_href);
     storeAppendPrintf(e, "</HEAD><BODY>\n");
     if (ftpState->cwd_message) {
 	storeAppendPrintf(e, "<PRE>\n");
@@ -697,7 +700,7 @@
 	}
     }
     /* {icon} {text} . . . {date}{size}{chdir}{view}{download}{link}\n  */
-    xstrncpy(href, rfc1738_escape(parts->name), 2048);
+    xstrncpy(href, rfc1738_escape_part(parts->name), 2048);
     xstrncpy(text, parts->showname, 2048);
     switch (parts->type) {
     case 'd':
@@ -830,6 +833,7 @@
 ftpReadComplete(FtpStateData * ftpState)
 {
     debug(9, 3) ("ftpReadComplete\n");
+    /* Connection closed; retrieval done. */
     if (ftpState->data.fd > -1) {
 	/*
 	 * close data socket so it does not occupy resources while
@@ -838,13 +842,6 @@
 	comm_close(ftpState->data.fd);
 	ftpState->data.fd = -1;
     }
-    /* Connection closed; retrieval done. */
-    if (ftpState->flags.html_header_sent)
-	ftpListingFinish(ftpState);
-    if (!ftpState->flags.put) {
-	storeTimestampsSet(ftpState->entry);
-	fwdComplete(ftpState->fwd);
-    }
     /* expect the "transfer complete" message on the control socket */
     ftpScheduleReadControlReply(ftpState, 1);
 }
@@ -903,8 +900,9 @@
 		data,
 		Config.Timeout.read);
 	} else {
-	    assert(mem->inmem_hi > 0);
-	    ftpDataTransferDone(ftpState);
+	    ftpFailed(ftpState, ERR_READ_ERROR);
+	    /* ftpFailed closes ctrl.fd and frees ftpState */
+	    return;
 	}
     } else if (len == 0) {
 	ftpReadComplete(ftpState);
@@ -938,12 +936,10 @@
     char *orig_user;
     const char *auth;
     ftpLoginParser(ftpState->request->login, ftpState, FTP_LOGIN_ESCAPED);
-    if (ftpState->user[0] && ftpState->password[0])
-	return 1;		/* name and passwd both in URL */
-    if (!ftpState->user[0] && !ftpState->password[0])
-	return 1;		/* no name or passwd */
-    if (ftpState->password[0])
-	return 1;		/* passwd with no name? */
+    if (!ftpState->user[0])
+	return 1;		/* no name */
+    if (ftpState->password_url || ftpState->password[0])
+	return 1;		/* passwd provided in URL */
     /* URL has name, but no passwd */
     if (!(auth = httpHeaderGetAuth(req_hdr, HDR_AUTHORIZATION, "Basic")))
 	return 0;		/* need auth header */
@@ -975,7 +971,6 @@
     ftpState->flags.use_base = 1;
     /* check for null path */
     if (!l) {
-	stringReset(&request->urlpath, "/");
 	ftpState->flags.isdir = 1;
 	ftpState->flags.root_dir = 1;
     } else if (!strCmp(request->urlpath, "/%2f/")) {
@@ -1013,6 +1008,21 @@
     if (request->port != urlDefaultPort(PROTO_FTP))
 	snprintf(&t[strlen(t)], len - strlen(t), ":%d", request->port);
     strcat(t, strBuf(request->urlpath));
+    t = ftpState->base_href = xcalloc(len, 1);
+    strcat(t, "ftp://");
+    if (strcmp(ftpState->user, "anonymous")) {
+	strcat(t, rfc1738_escape_part(ftpState->user));
+	if (ftpState->password_url) {
+	    strcat(t, ":");
+	    strcat(t, rfc1738_escape_part(ftpState->password));
+	}
+	strcat(t, "@");
+    }
+    strcat(t, request->host);
+    if (request->port != urlDefaultPort(PROTO_FTP))
+	snprintf(&t[strlen(t)], len - strlen(t), ":%d", request->port);
+    strcat(t, strBuf(request->urlpath));
+    strcat(t, "/");
 }
 
 void
@@ -1038,7 +1048,7 @@
     ftpState->data.fd = -1;
     ftpState->size = -1;
     ftpState->mdtm = -1;
-    ftpState->flags.pasv_supported = 1;
+    ftpState->flags.pasv_supported = !fwd->flags.ftp_pasv_failed;
     ftpState->flags.rest_supported = 1;
     ftpState->fwd = fwd;
     comm_add_close_handler(fd, ftpStateFree, ftpState);
@@ -1081,7 +1091,6 @@
     ftpState->data.size = SQUID_TCP_SO_RCVBUF;
     ftpState->data.freefunc = xfree;
     ftpScheduleReadControlReply(ftpState, 0);
-    commSetTimeout(fd, Config.Timeout.read, ftpTimeout, ftpState);
 }
 
 /* ====================================================================== */
@@ -1091,6 +1100,7 @@
 {
     debug(9, 5) ("ftpWriteCommand: %s\n", buf);
     safe_free(ftpState->ctrl.last_command);
+    safe_free(ftpState->ctrl.last_reply);
     ftpState->ctrl.last_command = xstrdup(buf);
     comm_write(ftpState->ctrl.fd,
 	xstrdup(buf),
@@ -1105,8 +1115,6 @@
 ftpWriteCommandCallback(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     FtpStateData *ftpState = data;
-    StoreEntry *entry = ftpState->entry;
-    ErrorState *err;
     debug(9, 7) ("ftpWriteCommandCallback: wrote %d bytes\n", size);
     if (size > 0) {
 	fd_bytes(fd, size, FD_WRITE);
@@ -1117,13 +1125,9 @@
 	return;
     if (errflag) {
 	debug(50, 1) ("ftpWriteCommandCallback: FD %d: %s\n", fd, xstrerror());
-	if (entry->mem_obj->inmem_hi == 0) {
-	    err = errorCon(ERR_WRITE_ERROR, HTTP_SERVICE_UNAVAILABLE);
-	    err->xerrno = errno;
-	    err->request = requestLink(ftpState->request);
-	    errorAppendEntry(entry, err);
-	}
-	comm_close(ftpState->ctrl.fd);
+	ftpFailed(ftpState, ERR_WRITE_ERROR);
+	/* ftpFailed closes ctrl.fd and frees ftpState */
+	return;
     }
 }
 
@@ -1205,6 +1209,14 @@
 	    ftpReadControlReply,
 	    ftpState,
 	    Config.Timeout.read);
+	/*
+	 * Cancel the timeout on the Data socket (if any) and
+	 * establish one on the control socket.
+	 */
+	if (ftpState->data.fd > -1)
+	    commSetTimeout(ftpState->data.fd, -1, NULL, NULL);
+	commSetTimeout(ftpState->ctrl.fd, Config.Timeout.read, ftpTimeout,
+	    ftpState);
     }
 }
 
@@ -1214,8 +1226,11 @@
     FtpStateData *ftpState = data;
     StoreEntry *entry = ftpState->entry;
     int len;
-    ErrorState *err;
     debug(9, 5) ("ftpReadControlReply\n");
+    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+	comm_close(ftpState->ctrl.fd);
+	return;
+    }
     assert(ftpState->ctrl.offset < ftpState->ctrl.size);
     Counter.syscalls.sock.reads++;
     len = read(fd,
@@ -1232,26 +1247,17 @@
 	if (ignoreErrno(errno)) {
 	    ftpScheduleReadControlReply(ftpState, 0);
 	} else {
-	    if (entry->mem_obj->inmem_hi == 0) {
-		err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
-		err->xerrno = errno;
-		err->request = requestLink(ftpState->request);
-		errorAppendEntry(entry, err);
-	    }
-	    comm_close(ftpState->ctrl.fd);
+	    ftpFailed(ftpState, ERR_READ_ERROR);
+	    /* ftpFailed closes ctrl.fd and frees ftpState */
+	    return;
 	}
 	return;
     }
     if (len == 0) {
 	if (entry->store_status == STORE_PENDING) {
-	    storeReleaseRequest(entry);
-	    if (entry->mem_obj->inmem_hi == 0) {
-		err = errorCon(ERR_FTP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
-		err->xerrno = 0;
-		err->request = requestLink(ftpState->request);
-		err->ftp_server_msg = ftpState->ctrl.message;
-		errorAppendEntry(entry, err);
-	    }
+	    ftpFailed(ftpState, ERR_FTP_FAILURE);
+	    /* ftpFailed closes ctrl.fd and frees ftpState */
+	    return;
 	}
 	comm_close(ftpState->ctrl.fd);
 	return;
@@ -1298,7 +1304,7 @@
     safe_free(ftpState->ctrl.last_reply);
     ftpState->ctrl.last_reply = (*W)->key;
     safe_free(*W);
-    debug(9, 8) ("ftpReadControlReply: state=%d, code=%d\n", ftpState->state,
+    debug(9, 8) ("ftpHandleControlReply: state=%d, code=%d\n", ftpState->state,
 	ftpState->ctrl.replycode);
     FTP_SM_FUNCS[ftpState->state] (ftpState);
 }
@@ -1312,6 +1318,8 @@
     debug(9, 3) ("ftpReadWelcome\n");
     if (ftpState->flags.pasv_only)
 	ftpState->login_att++;
+    /* Dont retry if the FTP server accepted the connection */
+    ftpState->fwd->flags.dont_retry = 1;
     if (code == 220) {
 	if (ftpState->ctrl.message) {
 	    if (strstr(ftpState->ctrl.message->key, "NetWare"))
@@ -1372,13 +1380,13 @@
 {
     int code = ftpState->ctrl.replycode;
     debug(9, 3) ("ftpReadPass\n");
-    if (ftpState->ctrl.message) {
-	if (ftpState->cwd_message)
-	    wordlistDestroy(&ftpState->cwd_message);
-	ftpState->cwd_message = ftpState->ctrl.message;
-	ftpState->ctrl.message = NULL;
-    }
     if (code == 230) {
+	if (ftpState->ctrl.message) {
+	    if (ftpState->cwd_message)
+		wordlistDestroy(&ftpState->cwd_message);
+	    ftpState->cwd_message = ftpState->ctrl.message;
+	    ftpState->ctrl.message = NULL;
+	}
 	ftpSendType(ftpState);
     } else {
 	ftpFail(ftpState);
@@ -1677,6 +1685,11 @@
     snprintf(cbuf, 1024, "PASV\r\n");
     ftpWriteCommand(cbuf, ftpState);
     ftpState->state = SENT_PASV;
+    /*
+     * ugly hack for ftp servers like ftp.netscape.com that sometimes
+     * dont acknowledge PORT commands.
+     */
+    commSetTimeout(ftpState->data.fd, 15, ftpTimeout, ftpState);
 }
 
 static void
@@ -1693,8 +1706,6 @@
     debug(9, 3) ("This is ftpReadPasv\n");
     if (code != 227) {
 	debug(9, 3) ("PASV not supported by remote end\n");
-	comm_close(ftpState->data.fd);
-	ftpState->data.fd = -1;
 	ftpSendPort(ftpState);
 	return;
     }
@@ -1729,6 +1740,9 @@
     debug(9, 5) ("ftpReadPasv: connecting to %s, port %d\n", junk, port);
     ftpState->data.port = port;
     ftpState->data.host = xstrdup(junk);
+    safe_free(ftpState->ctrl.last_command);
+    safe_free(ftpState->ctrl.last_reply);
+    ftpState->ctrl.last_command = xstrdup("Connect to server data port");
     commConnectStart(fd, junk, port, ftpPasvCallback, ftpState);
 }
 
@@ -1736,17 +1750,13 @@
 ftpPasvCallback(int fd, int status, void *data)
 {
     FtpStateData *ftpState = data;
-    request_t *request = ftpState->request;
-    ErrorState *err;
     debug(9, 3) ("ftpPasvCallback\n");
     if (status != COMM_OK) {
-	err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
-	err->xerrno = errno;
-	err->host = xstrdup(ftpState->data.host);
-	err->port = ftpState->data.port;
-	err->request = requestLink(request);
-	errorAppendEntry(ftpState->entry, err);
-	comm_close(ftpState->ctrl.fd);
+	debug(9, 2) ("ftpPasvCallback: failed to connect. Retrying without PASV.\n");
+	ftpState->fwd->flags.dont_retry = 0;	/* this is a retryable error */
+	ftpState->fwd->flags.ftp_pasv_failed = 1;
+	ftpFailed(ftpState, ERR_NONE);
+	/* ftpFailed closes ctrl.fd and frees ftpState */
 	return;
     }
     ftpRestOrList(ftpState);
@@ -1761,6 +1771,14 @@
     int on = 1;
     u_short port = 0;
     /*
+     * * Tear down any old data connection if any. We are about to
+     * * establish a new one.
+     */
+    if (ftpState->data.fd > 0) {
+	comm_close(ftpState->data.fd);
+	ftpState->data.fd = -1;
+    }
+    /*
      * Set up a listen socket on the same local address as the
      * control connection.
      */
@@ -1834,8 +1852,6 @@
     if (code != 200) {
 	/* Fall back on using the same port as the control connection */
 	debug(9, 3) ("PORT not supported by remote end\n");
-	comm_close(ftpState->data.fd);
-	ftpState->data.fd = -1;
 	ftpOpenListenSocket(ftpState, 1);
     }
     ftpRestOrList(ftpState);
@@ -1876,7 +1892,6 @@
 static void
 ftpRestOrList(FtpStateData * ftpState)
 {
-
     debug(9, 3) ("This is ftpRestOrList\n");
     if (ftpState->flags.put) {
 	debug(9, 3) ("ftpRestOrList: Sending STOR request...\n");
@@ -1897,10 +1912,20 @@
 static void
 ftpSendStor(FtpStateData * ftpState)
 {
-    assert(ftpState->filepath != NULL);
-    snprintf(cbuf, 1024, "STOR %s\r\n", ftpState->filepath);
-    ftpWriteCommand(cbuf, ftpState);
-    ftpState->state = SENT_STOR;
+    if (ftpState->filepath != NULL) {
+	/* Plain file upload */
+	snprintf(cbuf, 1024, "STOR %s\r\n", ftpState->filepath);
+	ftpWriteCommand(cbuf, ftpState);
+	ftpState->state = SENT_STOR;
+    } else if (httpHeaderGetInt(&ftpState->request->header, HDR_CONTENT_LENGTH) > 0) {
+	/* File upload without a filename. use STOU to generate one */
+	snprintf(cbuf, 1024, "STOU\r\n");
+	ftpWriteCommand(cbuf, ftpState);
+	ftpState->state = SENT_STOR;
+    } else {
+	/* No file to transfer. Only create directories if needed */
+	ftpSendReply(ftpState);
+    }
 }
 
 static void
@@ -1908,7 +1933,9 @@
 {
     int code = ftpState->ctrl.replycode;
     debug(9, 3) ("This is ftpReadStor\n");
-    if (code >= 100 && code < 200) {
+    if (code == 125 || (code == 150 && ftpState->data.host)) {
+	/* Begin data transfer */
+	debug(9, 3) ("ftpReadStor: starting data transfer\n");
 	/*
 	 * Cancel the timeout on the Control socket, pumpStart will
 	 * establish one on the data socket.
@@ -1917,15 +1944,17 @@
 	ftpPutStart(ftpState);
 	debug(9, 3) ("ftpReadStor: writing data channel\n");
 	ftpState->state = WRITING_DATA;
-    } else if (code == 553) {
-	/* directory does not exist, have to create, sigh */
-#if WORK_IN_PROGRESS
-	ftpTraverseDirectory(ftpState);
-#endif
-	ftpSendReply(ftpState);
+    } else if (code == 150) {
+	/* Accept data channel */
+	debug(9, 3) ("ftpReadStor: accepting data channel\n");
+	commSetSelect(ftpState->data.fd,
+	    COMM_SELECT_READ,
+	    ftpAcceptDataConnection,
+	    ftpState,
+	    0);
     } else {
-	debug(9, 3) ("ftpReadStor: that's all folks\n");
-	ftpSendReply(ftpState);
+	debug(9, 3) ("ftpReadStor: Unexpected reply code %s\n", code);
+	ftpFail(ftpState);
     }
 }
 
@@ -2107,13 +2136,22 @@
 {
     int code = ftpState->ctrl.replycode;
     debug(9, 3) ("This is ftpReadTransferDone\n");
-    if (code != 226) {
+    if (code == 226) {
+	/* Connection closed; retrieval done. */
+	if (ftpState->flags.html_header_sent)
+	    ftpListingFinish(ftpState);
+	if (!ftpState->flags.put) {
+	    storeTimestampsSet(ftpState->entry);
+	    fwdComplete(ftpState->fwd);
+	}
+	ftpDataTransferDone(ftpState);
+    } else {			/* != 226 */
 	debug(9, 1) ("ftpReadTransferDone: Got code %d after reading data\n",
 	    code);
-	debug(9, 1) ("--> releasing '%s'\n", storeUrl(ftpState->entry));
-	storeReleaseRequest(ftpState->entry);
+	ftpFailed(ftpState, ERR_FTP_FAILURE);
+	/* ftpFailed closes ctrl.fd and frees ftpState */
+	return;
     }
-    ftpDataTransferDone(ftpState);
 }
 
 static void
@@ -2212,7 +2250,6 @@
 static void
 ftpFail(FtpStateData * ftpState)
 {
-    ErrorState *err;
     debug(9, 3) ("ftpFail\n");
     /* Try the / hack to support "Netscape" FTP URL's for retreiving files */
     if (!ftpState->flags.isdir &&	/* Not a directory */
@@ -2243,45 +2280,80 @@
 	    break;
 	}
     }
+    ftpFailed(ftpState, ERR_NONE);
+    /* ftpFailed closes ctrl.fd and frees ftpState */
+}
+
+static void
+ftpFailed(FtpStateData * ftpState, err_type error)
+{
+    StoreEntry *entry = ftpState->entry;
+    if (entry->mem_obj->inmem_hi == 0)
+	ftpFailedErrorMessage(ftpState, error);
+    if (ftpState->data.fd > -1) {
+	comm_close(ftpState->data.fd);
+	ftpState->data.fd = -1;
+    }
+    comm_close(ftpState->ctrl.fd);
+}
+
+static void
+ftpFailedErrorMessage(FtpStateData * ftpState, err_type error)
+{
+    ErrorState *err;
+    char *command, *reply;
     /* Translate FTP errors into HTTP errors */
     err = NULL;
-    switch (ftpState->state) {
-    case SENT_USER:
-    case SENT_PASS:
-	if (ftpState->ctrl.replycode > 500)
-	    err = errorCon(ERR_FTP_FORBIDDEN, HTTP_FORBIDDEN);
-	else if (ftpState->ctrl.replycode == 421)
-	    err = errorCon(ERR_FTP_UNAVAILABLE, HTTP_SERVICE_UNAVAILABLE);
+    switch (error) {
+    case ERR_NONE:
+	switch (ftpState->state) {
+	case SENT_USER:
+	case SENT_PASS:
+	    if (ftpState->ctrl.replycode > 500)
+		err = errorCon(ERR_FTP_FORBIDDEN, HTTP_FORBIDDEN);
+	    else if (ftpState->ctrl.replycode == 421)
+		err = errorCon(ERR_FTP_UNAVAILABLE, HTTP_SERVICE_UNAVAILABLE);
+	    break;
+	case SENT_CWD:
+	case SENT_RETR:
+	    if (ftpState->ctrl.replycode == 550)
+		err = errorCon(ERR_FTP_NOT_FOUND, HTTP_NOT_FOUND);
+	    break;
+	default:
+	    break;
+	}
 	break;
-    case SENT_CWD:
-    case SENT_RETR:
-	if (ftpState->ctrl.replycode == 550)
-	    err = errorCon(ERR_FTP_NOT_FOUND, HTTP_NOT_FOUND);
+    case ERR_READ_TIMEOUT:
+	err = errorCon(error, HTTP_GATEWAY_TIMEOUT);
 	break;
     default:
+	err = errorCon(error, HTTP_BAD_GATEWAY);
 	break;
     }
     if (err == NULL)
 	err = errorCon(ERR_FTP_FAILURE, HTTP_BAD_GATEWAY);
+    err->xerrno = errno;
     err->request = requestLink(ftpState->request);
-    err->ftp_server_msg = ftpState->ctrl.message;
+    err->ftp.server_msg = ftpState->ctrl.message;
+    ftpState->ctrl.message = NULL;
     if (ftpState->old_request)
-	err->ftp.request = ftpState->old_request;
+	command = ftpState->old_request;
     else
-	err->ftp.request = ftpState->ctrl.last_command;
-    if (err->ftp.request) {
-	if (!strncmp(err->ftp.request, "PASS", 4))
-	    err->ftp.request = "PASS <yourpassword>";
-    }
+	command = ftpState->ctrl.last_command;
+    if (command && strncmp(command, "PASS", 4) == 0)
+	command = "PASS <yourpassword>";
     if (ftpState->old_reply)
-	err->ftp.reply = ftpState->old_reply;
+	reply = ftpState->old_reply;
     else
-	err->ftp.reply = ftpState->ctrl.last_reply;
-    errorAppendEntry(ftpState->entry, err);
-    comm_close(ftpState->ctrl.fd);
+	reply = ftpState->ctrl.last_reply;
+    if (command)
+	err->ftp.request = xstrdup(command);
+    if (reply)
+	err->ftp.reply = xstrdup(reply);
+    fwdFail(ftpState->fwd, err);
 }
 
-void
+static void
 ftpPumpClosedData(int data_fd, void *data)
 {
     FtpStateData *ftpState = data;
@@ -2337,6 +2409,9 @@
     if (code == 226) {
 	err_code = (ftpState->mdtm > 0) ? ERR_FTP_PUT_MODIFIED : ERR_FTP_PUT_CREATED;
 	http_code = (ftpState->mdtm > 0) ? HTTP_ACCEPTED : HTTP_CREATED;
+    } else if (code == 227) {
+	err_code = ERR_FTP_PUT_CREATED;
+	http_code = HTTP_CREATED;
     } else {
 	err_code = ERR_FTP_PUT_ERROR;
 	http_code = HTTP_INTERNAL_SERVER_ERROR;
@@ -2344,16 +2419,16 @@
     err = errorCon(err_code, http_code);
     err->request = requestLink(ftpState->request);
     if (ftpState->old_request)
-	err->ftp.request = ftpState->old_request;
+	err->ftp.request = xstrdup(ftpState->old_request);
     else
-	err->ftp.request = ftpState->ctrl.last_command;
+	err->ftp.request = xstrdup(ftpState->ctrl.last_command);
     if (ftpState->old_reply)
-	err->ftp.reply = ftpState->old_reply;
+	err->ftp.reply = xstrdup(ftpState->old_reply);
     else
-	err->ftp.reply = ftpState->ctrl.last_reply;
+	err->ftp.reply = xstrdup(ftpState->ctrl.last_reply);
     errorAppendEntry(ftpState->entry, err);
     storeBufferFlush(ftpState->entry);
-    comm_close(ftpState->ctrl.fd);
+    ftpSendQuit(ftpState);
 }
 
 static void
Index: squid/src/globals.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/globals.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/globals.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/globals.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: globals.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: globals.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -92,6 +92,7 @@
 extern int syslog_enable;	/* 0 */
 extern int theInIcpConnection;	/* -1 */
 extern int theOutIcpConnection;	/* -1 */
+extern int DnsSocket;		/* -1 */
 #ifdef SQUID_SNMP
 extern int theInSnmpConnection;	/* -1 */
 extern int theOutSnmpConnection;	/* -1 */
@@ -111,7 +112,7 @@
 extern time_t squid_curtime;	/* 0 */
 extern int shutting_down;	/* 0 */
 extern int reconfiguring;	/* 0 */
-extern int store_rebuilding;	/* 1 */
+extern int store_dirs_rebuilding;	/* 1 */
 extern int store_swap_size;	/* 0 */
 extern unsigned long store_mem_size;	/* 0 */
 extern time_t hit_only_mode_until;	/* 0 */
@@ -124,7 +125,12 @@
 extern double current_dtime;
 extern int store_hash_buckets;	/* 0 */
 extern hash_table *store_table;	/* NULL */
+#if HEAP_REPLACEMENT
+extern heap *store_heap;
+extern heap *inmem_heap;
+#else
 extern dlink_list store_list;
+#endif
 extern dlink_list ClientActiveRequests;
 extern const String StringNull;	/* { 0, 0, NULL } */
 extern const MemBuf MemBufNull;	/* MemBufNULL */
@@ -144,3 +150,4 @@
 #endif
 extern request_flags null_request_flags;
 extern int store_open_disk_fd;	/* 0 */
+extern const char *SwapDirType[];
Index: squid/src/gopher.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/gopher.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/gopher.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/gopher.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: gopher.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: gopher.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 10    Gopher
  * AUTHOR: Harvest Derived
@@ -430,7 +430,7 @@
 				port[0] = 0;	/* 0 means none */
 			}
 			/* escape a selector here */
-			escaped_selector = xstrdup(rfc1738_escape(selector));
+			escaped_selector = xstrdup(rfc1738_escape_part(selector));
 
 			switch (gtype) {
 			case GOPHER_DIRECTORY:
Index: squid/src/helper.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/helper.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/helper.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/helper.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -231,7 +231,6 @@
     if (!srv->flags.shutdown) {
 	debug(34, 0) ("WARNING: %s #%d (FD %d) exited\n",
 	    hlp->id_name, srv->index + 1, fd);
-	assert(hlp->n_running >= hlp->n_to_start / 2);
 	if (hlp->n_running < hlp->n_to_start / 2)
 	    fatalf("Too few %s processes are running", hlp->id_name);
     }
Index: squid/src/htcp.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/htcp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/src/htcp.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/src/htcp.c	26 Jan 2000 03:25:01 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: htcp.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: htcp.c,v 1.1.1.2 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 31    Hypertext Caching Protocol
  * AUTHOR: Duane Wesssels
@@ -57,20 +57,20 @@
 struct _htcpDataHeader {
     u_short length;
 #if !WORDS_BIGENDIAN
-    u_char opcode:4;
-    u_char response:4;
+    unsigned int opcode:4;
+    unsigned int response:4;
 #else
-    u_char response:4;
-    u_char opcode:4;
+    unsigned int response:4;
+    unsigned int opcode:4;
 #endif
 #if !WORDS_BIGENDIAN
-    u_char reserved:6;
-    u_char F1:1;
-    u_char RR:1;
+    unsigned int reserved:6;
+    unsigned int F1:1;
+    unsigned int RR:1;
 #else
-    u_char RR:1;
-    u_char F1:1;
-    u_char reserved:6;
+    unsigned int RR:1;
+    unsigned int F1:1;
+    unsigned int reserved:6;
 #endif
     u_num32 msg_id;
 };
@@ -180,6 +180,7 @@
 static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, struct sockaddr_in *);
 static void htcpHandleTstRequest(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
 static void htcpHandleTstResponse(htcpDataHeader *, char *, int, struct sockaddr_in *);
+static StoreEntry *htcpCheckHit(const htcpSpecifier *);
 
 static void
 htcpHexdump(const char *tag, const char *s, int sz)
@@ -364,16 +365,22 @@
     htcpHeader hdr;
     char *buf = xcalloc(buflen, 1);
     /* skip the header -- we don't know the overall length */
-    if (buflen < hdr_sz)
+    if (buflen < hdr_sz) {
+	xfree(buf);
 	return NULL;
+    }
     off += hdr_sz;
     s = htcpBuildData(buf + off, buflen - off, stuff);
-    if (s < 0)
+    if (s < 0) {
+	xfree(buf);
 	return NULL;
+    }
     off += s;
     s = htcpBuildAuth(buf + off, buflen - off);
-    if (s < 0)
+    if (s < 0) {
+	xfree(buf);
 	return NULL;
+    }
     off += s;
     hdr.length = htons((u_short) off);
     hdr.major = 0;
@@ -411,7 +418,7 @@
     safe_free(s->uri);
     safe_free(s->version);
     safe_free(s->req_hdrs);
-    xfree(s);
+    memFree(s, MEM_HTCP_SPECIFIER);
 }
 
 static void
@@ -420,7 +427,7 @@
     safe_free(d->resp_hdrs);
     safe_free(d->entity_hdrs);
     safe_free(d->cache_hdrs);
-    xfree(d);
+    memFree(d, MEM_HTCP_DETAIL);
 }
 
 static int
@@ -453,7 +460,7 @@
 static htcpSpecifier *
 htcpUnpackSpecifier(char *buf, int sz)
 {
-    htcpSpecifier *s = xcalloc(1, sizeof(htcpSpecifier));
+    htcpSpecifier *s = memAllocate(MEM_HTCP_SPECIFIER);
     int o;
     debug(31, 3) ("htcpUnpackSpecifier: %d bytes\n", (int) sz);
     o = htcpUnpackCountstr(buf, sz, &s->method);
@@ -495,7 +502,7 @@
 static htcpDetail *
 htcpUnpackDetail(char *buf, int sz)
 {
-    htcpDetail *d = xcalloc(1, sizeof(htcpDetail));
+    htcpDetail *d = memAllocate(MEM_HTCP_DETAIL);
     int o;
     debug(31, 3) ("htcpUnpackDetail: %d bytes\n", (int) sz);
     o = htcpUnpackCountstr(buf, sz, &d->resp_hdrs);
@@ -540,10 +547,12 @@
     int hops = 0;
     int samp = 0;
     char cto_buf[128];
+    memset(&stuff, '\0', sizeof(stuff));
     stuff.op = HTCP_TST;
     stuff.rr = RR_RESPONSE;
     stuff.f1 = 0;
     stuff.response = e ? 0 : 1;
+    debug(31, 3) ("htcpTstReply: response = %d\n", stuff.response);
     stuff.msg_id = dhdr->msg_id;
     if (spec) {
 	memBufDefInit(&mb);
@@ -600,6 +609,40 @@
     debug(31, 3) ("htcpHandleNop: Unimplemented\n");
 }
 
+static StoreEntry *
+htcpCheckHit(const htcpSpecifier * s)
+{
+    request_t *request;
+    method_t m = urlParseMethod(s->method);
+    StoreEntry *e = storeGetPublic(s->uri, m);
+    char *blk_end;
+    if (NULL == e) {
+	debug(31, 3) ("htcpCheckHit: NO; public object not found\n");
+	return NULL;
+    }
+    if (!storeEntryValidToSend(e)) {
+	debug(31, 3) ("htcpCheckHit: NO; entry not valid to send\n");
+	return NULL;
+    }
+    request = urlParse(m, s->uri);
+    if (NULL == request) {
+	debug(31, 3) ("htcpCheckHit: NO; failed to parse URL\n");
+	return NULL;
+    }
+    blk_end = s->req_hdrs + strlen(s->req_hdrs);
+    if (!httpHeaderParse(&request->header, s->req_hdrs, blk_end)) {
+	debug(31, 3) ("htcpCheckHit: NO; failed to parse request headers\n");
+	e = NULL;
+    } else if (refreshCheckHTCP(e, request)) {
+	debug(31, 3) ("htcpCheckHit: NO; cached response is stale\n");
+	e = NULL;
+    } else {
+	debug(31, 3) ("htcpCheckHit: YES!?\n");
+    }
+    requestDestroy(request);
+    return e;
+}
+
 static void
 htcpHandleTst(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
 {
@@ -645,6 +688,7 @@
     key = queried_keys[htcpReply.msg_id % N_QUERIED_KEYS];
     debug(31, 3) ("htcpHandleTstResponse: key (%p) %s\n", key, storeKeyText(key));
     neighborsHtcpReply(key, &htcpReply, from);
+    httpHeaderClean(&htcpReply.hdr);
     if (d)
 	htcpFreeDetail(d);
 }
@@ -655,7 +699,6 @@
     /* buf should be a SPECIFIER */
     htcpSpecifier *s;
     StoreEntry *e;
-    method_t m;
     if (sz == 0) {
 	debug(31, 3) ("htcpHandleTst: nothing to do\n");
 	return;
@@ -671,21 +714,11 @@
 	s->method,
 	s->uri,
 	s->version);
-    m = urlParseMethod(s->method);
     debug(31, 3) ("htcpHandleTstRequest: %s\n", s->req_hdrs);
-    e = storeGetPublic(s->uri, m);
-    if (NULL == e) {
-	/* cache miss */
-	htcpTstReply(dhdr, NULL, NULL, from);
-#if WIP
-    } else if (!checkHeaders()) {
-	/* refresh/other miss */
-	htcpTstReply(dhdr, NULL, NULL, from);
-#endif
-    } else {
-	/* hit */
-	htcpTstReply(dhdr, e, s, from);
-    }
+    if ((e = htcpCheckHit(s)))
+	htcpTstReply(dhdr, e, s, from);		/* hit */
+    else
+	htcpTstReply(dhdr, NULL, NULL, from);	/* cache miss */
     htcpFreeSpecifier(s);
 }
 
@@ -772,7 +805,7 @@
     debug(31, 3) ("htcpHandle: htcpHdr.major = %d\n", (int) htcpHdr.major);
     debug(31, 3) ("htcpHandle: htcpHdr.minor = %d\n", (int) htcpHdr.minor);
     if (sz != htcpHdr.length) {
-	debug(31, 0) ("htcpHandle: sz != htcpHdr.length\n");
+	debug(31, 1) ("htcpHandle: sz != htcpHdr.length\n");
 	return;
     }
     buf += sizeof(htcpHeader);
@@ -836,6 +869,8 @@
     } else {
 	htcpOutSocket = htcpInSocket;
     }
+    memDataInit(MEM_HTCP_SPECIFIER, "htcpSpecifier", sizeof(htcpSpecifier), 0);
+    memDataInit(MEM_HTCP_DETAIL, "htcpDetail", sizeof(htcpDetail), 0);
 }
 
 void
@@ -868,6 +903,7 @@
     packerClean(&pa);
     stuff.S.req_hdrs = mb.buf;
     pkt = htcpBuildPacket(&stuff, &pktlen);
+    memBufClean(&mb);
     if (pkt == NULL) {
 	debug(31, 0) ("htcpQuery: htcpBuildPacket() failed\n");
 	return;
Index: squid/src/http.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/http.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/http.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/http.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: http.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: http.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -132,6 +132,7 @@
 httpMaybeRemovePublic(StoreEntry * e, http_status status)
 {
     int remove = 0;
+    int forbidden = 0;
     StoreEntry *pe;
     if (!EBIT_TEST(e->flags, KEY_PRIVATE))
 	return;
@@ -141,34 +142,61 @@
     case HTTP_MULTIPLE_CHOICES:
     case HTTP_MOVED_PERMANENTLY:
     case HTTP_MOVED_TEMPORARILY:
-    case HTTP_FORBIDDEN:
-    case HTTP_NOT_FOUND:
-    case HTTP_METHOD_NOT_ALLOWED:
     case HTTP_GONE:
+    case HTTP_NOT_FOUND:
 	remove = 1;
 	break;
+    case HTTP_FORBIDDEN:
+    case HTTP_METHOD_NOT_ALLOWED:
+	forbidden = 1;
+	break;
 #if WORK_IN_PROGRESS
     case HTTP_UNAUTHORIZED:
-	remove = 1;
+	forbidden = 1;
 	break;
 #endif
     default:
-	remove = 0;
+#if QUESTIONABLE
+	/*
+	 * Any 2xx response should eject previously cached entities...
+	 */
+	if (status >= 200 && status < 300)
+	    remove = 1;
+#endif
 	break;
     }
-    if (!remove)
+    if (!remove && !forbidden)
 	return;
     assert(e->mem_obj);
     if ((pe = storeGetPublic(e->mem_obj->url, e->mem_obj->method)) != NULL) {
 	assert(e != pe);
 	storeRelease(pe);
     }
-    if (e->mem_obj->method == METHOD_GET) {
-	/* A fresh GET should eject old HEAD objects */
-	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {
+    /*
+     * Also remove any cached HEAD response in case the object has
+     * changed.
+     */
+    if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {
+	assert(e != pe);
+	storeRelease(pe);
+    }
+    if (forbidden)
+	return;
+    switch (e->mem_obj->method) {
+    case METHOD_PUT:
+    case METHOD_DELETE:
+    case METHOD_PROPPATCH:
+    case METHOD_MKCOL:
+    case METHOD_MOVE:
+	/*
+	 * Remove any cached GET object if it is beleived that the
+	 * object may have changed as a result of other methods
+	 */
+	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_GET)) != NULL) {
 	    assert(e != pe);
 	    storeRelease(pe);
 	}
+	break;
     }
 }
 
@@ -291,81 +319,80 @@
     char *t = NULL;
     StoreEntry *entry = httpState->entry;
     int room;
-    int hdr_len;
+    size_t hdr_len;
     HttpReply *reply = entry->mem_obj->reply;
+    Ctx ctx;
     debug(11, 3) ("httpProcessReplyHeader: key '%s'\n",
 	storeKeyText(entry->key));
     if (httpState->reply_hdr == NULL)
 	httpState->reply_hdr = memAllocate(MEM_8K_BUF);
-    if (httpState->reply_hdr_state == 0) {
-	hdr_len = strlen(httpState->reply_hdr);
-	room = 8191 - hdr_len;
-	strncat(httpState->reply_hdr, buf, room < size ? room : size);
-	hdr_len += room < size ? room : size;
-	if (hdr_len > 4 && strncmp(httpState->reply_hdr, "HTTP/", 5)) {
-	    debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", httpState->reply_hdr);
-	    httpState->reply_hdr_state += 2;
-	    reply->sline.status = HTTP_INVALID_HEADER;
-	    return;
-	}
-	t = httpState->reply_hdr + hdr_len;
-	/* headers can be incomplete only if object still arriving */
-	if (!httpState->eof) {
-	    size_t k = headersEnd(httpState->reply_hdr, 8192);
-	    if (0 == k)
-		return;		/* headers not complete */
-	    t = httpState->reply_hdr + k;
-	}
-	*t = '\0';
-	httpState->reply_hdr_state++;
-    }
-    if (httpState->reply_hdr_state == 1) {
-	const Ctx ctx = ctx_enter(entry->mem_obj->url);
-	httpState->reply_hdr_state++;
-	debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
-	    httpState->reply_hdr);
-	/* Parse headers into reply structure */
-	/* what happens if we fail to parse here? */
-	httpReplyParse(reply, httpState->reply_hdr);	/* httpState->eof); */
-	storeTimestampsSet(entry);
-	/* Check if object is cacheable or not based on reply code */
-	debug(11, 3) ("httpProcessReplyHeader: HTTP CODE: %d\n", reply->sline.status);
-	if (neighbors_do_private_keys)
-	    httpMaybeRemovePublic(entry, reply->sline.status);
-	switch (httpCachableReply(httpState)) {
-	case 1:
-	    httpMakePublic(entry);
-	    break;
-	case 0:
-	    httpMakePrivate(entry);
-	    break;
-	case -1:
-	    httpCacheNegatively(entry);
-	    break;
-	default:
-	    assert(0);
-	    break;
-	}
-	if (reply->cache_control) {
-	    if (EBIT_TEST(reply->cache_control->mask, CC_PROXY_REVALIDATE))
-		EBIT_SET(entry->flags, ENTRY_REVALIDATE);
-	    else if (EBIT_TEST(reply->cache_control->mask, CC_MUST_REVALIDATE))
-		EBIT_SET(entry->flags, ENTRY_REVALIDATE);
-	}
-	if (httpState->flags.keepalive)
-	    if (httpState->peer)
-		httpState->peer->stats.n_keepalives_sent++;
-	if (reply->keep_alive)
-	    if (httpState->peer)
-		httpState->peer->stats.n_keepalives_recv++;
-	ctx_exit(ctx);
-	if (reply->date > -1 && !httpState->peer) {
-	    int skew = abs(reply->date - squid_curtime);
-	    if (skew > 86400)
-		debug(11, 3) ("%s's clock is skewed by %d seconds!\n",
-		    httpState->request->host, skew);
-	}
+    assert(httpState->reply_hdr_state == 0);
+    hdr_len = strlen(httpState->reply_hdr);
+    room = 8191 - hdr_len;
+    strncat(httpState->reply_hdr, buf, room < size ? room : size);
+    hdr_len += room < size ? room : size;
+    if (hdr_len > 4 && strncmp(httpState->reply_hdr, "HTTP/", 5)) {
+	debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", httpState->reply_hdr);
+	httpState->reply_hdr_state += 2;
+	reply->sline.status = HTTP_INVALID_HEADER;
+	return;
+    }
+    t = httpState->reply_hdr + hdr_len;
+    /* headers can be incomplete only if object still arriving */
+    if (!httpState->eof) {
+	size_t k = headersEnd(httpState->reply_hdr, 8192);
+	if (0 == k)
+	    return;		/* headers not complete */
+	t = httpState->reply_hdr + k;
+    }
+    *t = '\0';
+    httpState->reply_hdr_state++;
+    assert(httpState->reply_hdr_state == 1);
+    ctx = ctx_enter(entry->mem_obj->url);
+    httpState->reply_hdr_state++;
+    debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
+	httpState->reply_hdr);
+    /* Parse headers into reply structure */
+    /* what happens if we fail to parse here? */
+    httpReplyParse(reply, httpState->reply_hdr, hdr_len);
+    storeTimestampsSet(entry);
+    /* Check if object is cacheable or not based on reply code */
+    debug(11, 3) ("httpProcessReplyHeader: HTTP CODE: %d\n", reply->sline.status);
+    if (neighbors_do_private_keys)
+	httpMaybeRemovePublic(entry, reply->sline.status);
+    switch (httpCachableReply(httpState)) {
+    case 1:
+	httpMakePublic(entry);
+	break;
+    case 0:
+	httpMakePrivate(entry);
+	break;
+    case -1:
+	httpCacheNegatively(entry);
+	break;
+    default:
+	assert(0);
+	break;
+    }
+    if (reply->cache_control) {
+	if (EBIT_TEST(reply->cache_control->mask, CC_PROXY_REVALIDATE))
+	    EBIT_SET(entry->flags, ENTRY_REVALIDATE);
+	else if (EBIT_TEST(reply->cache_control->mask, CC_MUST_REVALIDATE))
+	    EBIT_SET(entry->flags, ENTRY_REVALIDATE);
+    }
+    if (httpState->flags.keepalive)
+	if (httpState->peer)
+	    httpState->peer->stats.n_keepalives_sent++;
+    if (reply->keep_alive)
+	if (httpState->peer)
+	    httpState->peer->stats.n_keepalives_recv++;
+    if (reply->date > -1 && !httpState->peer) {
+	int skew = abs(reply->date - squid_curtime);
+	if (skew > 86400)
+	    debug(11, 3) ("%s's clock is skewed by %d seconds!\n",
+		httpState->request->host, skew);
     }
+    ctx_exit(ctx);
 }
 
 static int
@@ -374,6 +401,7 @@
     /* return 1 if we got the last of the data on a persistent connection */
     MemObject *mem = httpState->entry->mem_obj;
     HttpReply *reply = mem->reply;
+    int clen;
     debug(11, 3) ("httpPconnTransferDone: FD %d\n", httpState->fd);
     /*
      * If we didn't send a keep-alive request header, then this
@@ -397,40 +425,21 @@
 	return 0;
     debug(11, 5) ("httpPconnTransferDone: content_length=%d\n",
 	reply->content_length);
-    /*
-     * Deal with gross HTTP stuff
-     *    - If we haven't seen the end of the reply headers, we can't
-     *      be persistent.
-     *    - For HEAD requests we're done.
-     *    - For "200 OK" check the content-length in the next block.
-     *    - For "204 No Content" (even with content-length) we're done.
-     *    - For "304 Not Modified" (even with content-length) we're done.
-     *    - 1XX replies never have a body; we're done.
-     *    - For all other replies, check content length in next block.
-     */
+    /* If we haven't seen the end of reply headers, we are not done */
     if (httpState->reply_hdr_state < 2)
 	return 0;
-    else if (httpState->request->method == METHOD_HEAD)
-	return 1;
-    else if (reply->sline.status == HTTP_OK)
-	(void) 0;		/* common case, continue */
-    else if (reply->sline.status == HTTP_NO_CONTENT)
+    clen = httpReplyBodySize(httpState->request->method, reply);
+    /* If there is no message body, we can be persistent */
+    if (0 == clen)
 	return 1;
-    else if (reply->sline.status == HTTP_NOT_MODIFIED)
-	return 1;
-    else if (reply->sline.status < HTTP_OK)
-	return 1;
-    /*
-     * If there is no content-length, then we can't be
-     * persistent.  If there is a content length, then we must
-     * wait until we've seen the end of the body.
-     */
-    if (reply->content_length < 0)
+    /* If the body size is unknown we must wait for EOF */
+    if (clen < 0)
 	return 0;
-    else if (mem->inmem_hi < reply->content_length + reply->hdr_sz)
+    /* If the body size is known, we must wait until we've gotten all of it.  */
+    if (mem->inmem_hi < reply->content_length + reply->hdr_sz)
 	return 0;
-    else
-	return 1;
+    /* We got it all */
+    return 1;
 }
 
 /* This will be called when data is ready to be read from fd.  Read until
@@ -631,8 +640,8 @@
     HttpHeaderPos pos = HttpHeaderInitPos;
     httpHeaderInit(hdr_out, hoRequest);
     /* append our IMS header */
-    if (entry && entry->lastmod > -1 && request->method == METHOD_GET)
-	httpHeaderPutTime(hdr_out, HDR_IF_MODIFIED_SINCE, entry->lastmod);
+    if (request->lastmod > -1 && request->method == METHOD_GET)
+	httpHeaderPutTime(hdr_out, HDR_IF_MODIFIED_SINCE, request->lastmod);
 
     /* decide if we want to do Ranges ourselves 
      * (and fetch the whole object now)
@@ -669,9 +678,16 @@
 		request->flags.auth = 0;	/* We have used the authentication */
 	    break;
 	case HDR_HOST:
-	    /* Don't use client's Host: header for redirected requests */
-	    if (!request->flags.redirected || !Config.onoff.redir_rewrites_host)
-		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+	    /*
+	     * Normally Squid does not copy the Host: header from
+	     * a client request into the forwarded request headers.
+	     * However, there is one case when we do: If the URL
+	     * went through our redirector and the admin configured
+	     * 'redir_rewrites_host' to be off.
+	     */
+	    if (request->flags.redirected)
+		if (!Config.onoff.redir_rewrites_host)
+		    httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 	    break;
 	case HDR_IF_MODIFIED_SINCE:
 	    /* append unless we added our own;
@@ -712,7 +728,7 @@
 	httpHeaderPutStr(hdr_out, HDR_USER_AGENT, Config.fake_ua);
 
     /* append Via */
-    {
+    if (httpRequestHdrAllowedByName(HDR_VIA)) {
 	String strVia = httpHeaderGetList(hdr_in, HDR_VIA);
 	snprintf(bbuf, BBUF_SZ, "%3.1f %s", orig_request->http_ver, ThisCache);
 	strListAdd(&strVia, bbuf, ',');
@@ -720,7 +736,7 @@
 	stringClean(&strVia);
     }
     /* append X-Forwarded-For */
-    {
+    if (httpRequestHdrAllowedByName(HDR_X_FORWARDED_FOR)) {
 	String strFwd = httpHeaderGetList(hdr_in, HDR_X_FORWARDED_FOR);
 	strListAdd(&strFwd, (cfd < 0 ? "unknown" : fd_table[cfd].ipaddr), ',');
 	httpHeaderPutStr(hdr_out, HDR_X_FORWARDED_FOR, strBuf(strFwd));
@@ -745,9 +761,9 @@
     }
     /* append Proxy-Authorization if configured for peer, and proxying */
     if (!httpHeaderHas(hdr_out, HDR_PROXY_AUTHORIZATION)) {
-	if (request->flags.proxying && request->peer_login) {
+	if (request->flags.proxying && orig_request->peer_login) {
 	    httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",
-		base64_encode(request->peer_login));
+		base64_encode(orig_request->peer_login));
 	}
     }
     /* append Cache-Control, add max-age if not there already */
@@ -779,7 +795,7 @@
 
 /* build request prefix and append it to a given MemBuf; 
  * return the length of the prefix */
-size_t
+mb_size_t
 httpBuildRequestPrefix(request_t * request,
     request_t * orig_request,
     StoreEntry * entry,
@@ -818,7 +834,7 @@
 
     debug(11, 5) ("httpSendRequest: FD %d: httpState %p.\n", httpState->fd, httpState);
 
-    if (pumpMethod(req->method))
+    if (httpState->orig_request->content_length > 0)
 	sendHeaderDone = httpSendRequestEntry;
     else
 	sendHeaderDone = httpSendComplete;
@@ -878,7 +894,7 @@
 	xstrncpy(proxy_req->host, httpState->peer->host, SQUIDHOSTNAMELEN);
 	proxy_req->port = httpState->peer->http_port;
 	proxy_req->flags = orig_req->flags;
-	proxy_req->peer_login = httpState->peer->login;
+	proxy_req->lastmod = orig_req->lastmod;
 	httpState->request = requestLink(proxy_req);
 	httpState->orig_request = requestLink(orig_req);
 	proxy_req->flags.proxying = 1;
Index: squid/src/icp_v2.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/icp_v2.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/icp_v2.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/icp_v2.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icp_v2.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: icp_v2.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 12    Internet Cache Protocol
  * AUTHOR: Duane Wessels
@@ -201,7 +201,13 @@
     header.reqnum = ntohl(header.reqnum);
     header.flags = ntohl(header.flags);
     header.pad = ntohl(header.pad);
-
+    /*
+     * Length field should match the number of bytes read
+     */
+    if (len != header.length) {
+	debug(12, 3) ("icpHandleIcpV2: ICP message is too small\n");
+	return;
+    }
     switch (header.opcode) {
     case ICP_QUERY:
 	/* We have a valid packet */
@@ -256,7 +262,7 @@
 		netdbPingSite(icp_request->host);
 	}
 	/* if store is rebuilding, return a UDP_HIT, but not a MISS */
-	if (store_rebuilding && opt_reload_hit_only) {
+	if (store_dirs_rebuilding && opt_reload_hit_only) {
 	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);
 	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
 	} else if (hit_only_mode_until > squid_curtime) {
@@ -421,7 +427,8 @@
 	0);
     for (s = Config.mcast_group_list; s; s = s->next)
 	ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL);
-    debug(12, 1) ("Accepting ICP messages on port %d, FD %d.\n",
+    debug(12, 1) ("Accepting ICP messages at %s, port %d, FD %d.\n",
+	inet_ntoa(Config.Addrs.udp_incoming),
 	(int) port, theInIcpConnection);
     if ((addr = Config.Addrs.udp_outgoing).s_addr != no_addr.s_addr) {
 	enter_suid();
Index: squid/src/icp_v3.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/icp_v3.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/icp_v3.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/icp_v3.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icp_v3.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: icp_v3.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 12    Internet Cache Protocol
  * AUTHOR: Duane Wessels
@@ -55,7 +55,13 @@
     header.reqnum = ntohl(header.reqnum);
     header.flags = ntohl(header.flags);
     header.pad = ntohl(header.pad);
-
+    /*
+     * Length field should match the number of bytes read
+     */
+    if (len != header.length) {
+	debug(12, 3) ("icpHandleIcpV3: ICP message is too small\n");
+	return;
+    }
     switch (header.opcode) {
     case ICP_QUERY:
 	/* We have a valid packet */
@@ -100,7 +106,7 @@
 	    break;
 	}
 	/* if store is rebuilding, return a UDP_HIT, but not a MISS */
-	if (opt_reload_hit_only && store_rebuilding) {
+	if (opt_reload_hit_only && store_dirs_rebuilding) {
 	    reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
 	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
 	} else if (hit_only_mode_until > squid_curtime) {
Index: squid/src/ident.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/ident.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/ident.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ident.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ident.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: ident.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 30    Ident (RFC 931)
  * AUTHOR: Duane Wessels
Index: squid/src/internal.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/internal.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/internal.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/internal.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: internal.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: internal.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 76    Internal Squid Object handling
  * AUTHOR: Duane, Alex, Henrik
@@ -46,10 +46,28 @@
     const char *upath = strBuf(request->urlpath);
     debug(76, 3) ("internalStart: %s requesting '%s'\n",
 	inet_ntoa(request->client_addr), upath);
-    if (0 == strcmp(upath, "/squid-internal-dynamic/netdb"))
+    if (0 == strcmp(upath, "/squid-internal-dynamic/netdb")) {
 	netdbBinaryExchange(entry);
-    else {
-	debugObj(76, 1, "internalStart: unknown request:\n", request, (ObjPackMethod) & httpRequestPack);
+    } else if (0 == strcmp(upath, "/squid-internal-periodic/store_digest")) {
+#if USE_CACHE_DIGESTS
+	const char *msgbuf = "This cache is currently building its digest.\n";
+#else
+	const char *msgbuf = "This cache does not suport Cache Digests.\n";
+#endif
+	httpReplySetHeaders(entry->mem_obj->reply,
+	    1.0,
+	    HTTP_NOT_FOUND,
+	    "Not Found",
+	    "text/plain",
+	    strlen(msgbuf),
+	    squid_curtime,
+	    -2);
+	httpReplySwapOut(entry->mem_obj->reply, entry);
+	storeAppend(entry, msgbuf, strlen(msgbuf));
+	storeComplete(entry);
+    } else {
+	debugObj(76, 1, "internalStart: unknown request:\n",
+	    request, (ObjPackMethod) & httpRequestPack);
 	err = errorCon(ERR_INVALID_REQ, HTTP_NOT_FOUND);
 	err->request = requestLink(request);
 	errorAppendEntry(entry, err);
@@ -99,7 +117,8 @@
 char *
 internalLocalUri(const char *dir, const char *name)
 {
-    return internalRemoteUri(getMyHostname(), Config.Port.http->i, dir, name);
+    return internalRemoteUri(getMyHostname(),
+	ntohs(Config.Sockaddr.http->s.sin_port), dir, name);
 }
 
 const char *
@@ -110,3 +129,15 @@
     Tolower(host);
     return host;
 }
+
+int
+internalHostnameIs(const char *arg)
+{
+    wordlist *w;
+    if (0 == strcmp(arg, internalHostname()))
+	return 1;
+    for (w = Config.hostnameAliases; w; w = w->next)
+	if (0 == strcmp(arg, w->key))
+	    return 1;
+    return 0;
+}
Index: squid/src/ipc.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/ipc.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/ipc.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ipc.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipc.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: ipc.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 54    Interprocess Communication
  * AUTHOR: Duane Wessels
@@ -182,15 +182,16 @@
 	}
 	memset(hello_buf, '\0', HELLO_BUF_SZ);
 	if (type == IPC_UDP_SOCKET)
-	    x = recv(prfd, hello_buf, HELLO_BUF_SZ, 0);
+	    x = recv(prfd, hello_buf, HELLO_BUF_SZ - 1, 0);
 	else
-	    x = read(prfd, hello_buf, HELLO_BUF_SZ);
+	    x = read(prfd, hello_buf, HELLO_BUF_SZ - 1);
 	if (x < 0) {
 	    debug(50, 0) ("ipcCreate: PARENT: hello read test failed\n");
 	    debug(50, 0) ("--> read: %s\n", xstrerror());
 	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
 	} else if (strcmp(hello_buf, hello_string)) {
 	    debug(54, 0) ("ipcCreate: PARENT: hello read test failed\n");
+	    debug(54, 0) ("--> read returned %d\n", x);
 	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf));
 	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
 	}
@@ -251,7 +252,8 @@
      */
     do {
 	x = open(_PATH_DEVNULL, 0, 0444);
-	commSetCloseOnExec(x);
+	if (x > -1)
+	    commSetCloseOnExec(x);
     } while (x < 3);
     t1 = dup(crfd);
     t2 = dup(cwfd);
Index: squid/src/ipcache.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/ipcache.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/ipcache.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ipcache.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipcache.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: ipcache.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 14    IP Cache
  * AUTHOR: Harvest Derived
@@ -50,12 +50,20 @@
 static dlink_list lru_list;
 
 static FREE ipcacheFreeEntry;
+#if USE_DNSSERVERS
 static HLPCB ipcacheHandleReply;
+#else
+static IDNSCB ipcacheHandleReply;
+#endif
 static IPH dummy_handler;
 static int ipcacheExpiredEntry(ipcache_entry *);
 static int ipcache_testname(void);
 static ipcache_entry *ipcacheAddNew(const char *, const struct hostent *, ipcache_status_t);
+#if USE_DNSSERVERS
 static ipcache_entry *ipcacheParse(const char *buf);
+#else
+static ipcache_entry *ipcacheParse(rfc1035_rr *, int);
+#endif
 static ipcache_entry *ipcache_create(const char *name);
 static ipcache_entry *ipcache_get(const char *);
 static void ipcacheAddHostent(ipcache_entry *, const struct hostent *);
@@ -147,7 +155,8 @@
     if (i->locks != 0)
 	return 0;
     if (i->addrs.count == 0)
-	return 1;
+	if (i->status != IP_NEGATIVE_CACHED)
+	    return 1;
     if (i->expires > squid_curtime)
 	return 0;
     return 1;
@@ -255,6 +264,7 @@
 }
 
 static ipcache_entry *
+#if USE_DNSSERVERS
 ipcacheParse(const char *inbuf)
 {
     LOCAL_ARRAY(char, buf, DNS_INBUF_SZ);
@@ -323,9 +333,69 @@
     i.addrs.count = (unsigned char) j;
     return &i;
 }
+#else
+ipcacheParse(rfc1035_rr * answers, int nr)
+{
+    static ipcache_entry i;
+    int k;
+    int j;
+    int na = 0;
+    memset(&i, '\0', sizeof(i));
+    i.expires = squid_curtime + Config.negativeDnsTtl;
+    i.status = IP_NEGATIVE_CACHED;
+    if (nr < 0) {
+	debug(14, 3) ("ipcacheParse: Lookup failed (error %d)\n",
+	    rfc1035_errno);
+	assert(rfc1035_error_message);
+	i.error_message = xstrdup(rfc1035_error_message);
+	return &i;
+    }
+    if (nr == 0) {
+	debug(14, 3) ("ipcacheParse: No DNS records\n");
+	i.error_message = xstrdup("No DNS records");
+	return &i;
+    }
+    assert(answers);
+    for (j = 0, k = 0; k < nr; k++) {
+	if (answers[k].type != RFC1035_TYPE_A)
+	    continue;
+	if (answers[k].class != RFC1035_CLASS_IN)
+	    continue;
+	na++;
+    }
+    if (na == 0) {
+	debug(14, 1) ("ipcacheParse: No Address records\n");
+	i.error_message = xstrdup("No Address records");
+	return &i;
+    }
+    i.status = IP_CACHED;
+    i.addrs.in_addrs = xcalloc(na, sizeof(struct in_addr));
+    i.addrs.bad_mask = xcalloc(na, sizeof(unsigned char));
+    i.addrs.count = (unsigned char) na;
+    for (j = 0, k = 0; k < nr; k++) {
+	if (answers[k].type != RFC1035_TYPE_A)
+	    continue;
+	if (answers[k].class != RFC1035_CLASS_IN)
+	    continue;
+	if (j == 0)
+	    i.expires = squid_curtime + answers[k].ttl;
+	assert(answers[k].rdlength == 4);
+	xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 4);
+	debug(14, 3) ("ipcacheParse: #%d %s\n",
+	    j - 1,
+	    inet_ntoa(i.addrs.in_addrs[j - 1]));
+    }
+    assert(j == na);
+    return &i;
+}
+#endif
 
 static void
+#if USE_DNSSERVERS
 ipcacheHandleReply(void *data, char *reply)
+#else
+ipcacheHandleReply(void *data, rfc1035_rr * answers, int na)
+#endif
 {
     int n;
     generic_cbdata *c = data;
@@ -337,7 +407,11 @@
     c = NULL;
     n = ++IpcacheStats.replies;
     statHistCount(&Counter.dns.svc_time, tvSubMsec(i->request_time, current_time));
+#if USE_DNSSERVERS
     x = ipcacheParse(reply);
+#else
+    x = ipcacheParse(answers, na);
+#endif
     assert(x);
     i->status = x->status;
     i->addrs = x->addrs;
@@ -420,7 +494,11 @@
     cbdataAdd(c, cbdataXfree, 0);
     i->status = IP_DISPATCHED;
     ipcacheLockEntry(i);
+#if USE_DNSSERVERS
     dnsSubmit(i->name, ipcacheHandleReply, c);
+#else
+    idnsALookup(i->name, ipcacheHandleReply, c);
+#endif
 }
 
 /* initialize the ipcache */
@@ -788,43 +866,50 @@
 variable_list *
 snmp_netIpFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
-
+    variable_list *Answer = NULL;
     debug(49, 5) ("snmp_netIpFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]);
     snmpDebugOid(5, Var->name, Var->name_length);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-    Answer->val_len = sizeof(snint);
-    Answer->val.integer = xmalloc(Answer->val_len);
-    Answer->type = SMI_COUNTER32;
-
     switch (Var->name[LEN_SQ_NET + 1]) {
     case IP_ENT:
-	*(Answer->val.integer) = memInUse(MEM_IPCACHE_ENTRY);
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    memInUse(MEM_IPCACHE_ENTRY),
+	    SMI_GAUGE32);
 	break;
     case IP_REQ:
-	*(Answer->val.integer) = IpcacheStats.requests;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.requests,
+	    SMI_COUNTER32);
 	break;
     case IP_HITS:
-	*(Answer->val.integer) = IpcacheStats.hits;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.hits,
+	    SMI_COUNTER32);
 	break;
     case IP_PENDHIT:
-	*(Answer->val.integer) = IpcacheStats.pending_hits;
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.pending_hits,
+	    SMI_GAUGE32);
 	break;
     case IP_NEGHIT:
-	*(Answer->val.integer) = IpcacheStats.negative_hits;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.negative_hits,
+	    SMI_COUNTER32);
 	break;
     case IP_MISS:
-	*(Answer->val.integer) = IpcacheStats.misses;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.misses,
+	    SMI_COUNTER32);
 	break;
     case IP_GHBN:
-	*(Answer->val.integer) = IpcacheStats.ghbn_calls;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.ghbn_calls,
+	    SMI_COUNTER32);
 	break;
     case IP_LOC:
-	*(Answer->val.integer) = IpcacheStats.release_locked;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IpcacheStats.release_locked,
+	    SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
Index: squid/src/main.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/main.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/main.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/main.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: main.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -72,6 +72,10 @@
 static EVH SquidShutdown;
 static void mainSetCwd(void);
 
+#if TEST_ACCESS
+#include "test_access.c"
+#endif
+
 static void
 usage(void)
 {
@@ -91,7 +95,7 @@
 	"       -z        Create swap directories\n"
 	"       -C        Do not catch fatal signals.\n"
 	"       -D        Disable initial DNS tests.\n"
-	"       -F        Foreground fast store rebuild.\n"
+	"       -F        Don't serve any requests until store is rebuilt.\n"
 	"       -N        No daemon mode.\n"
 	"       -R        Do not set REUSEADDR on port.\n"
 	"       -V        Virtual host httpd-accelerator.\n"
@@ -280,6 +284,9 @@
 #ifdef SQUID_SNMP
     snmpConnectionOpen();
 #endif
+#if USE_WCCP
+    wccpConnectionOpen();
+#endif
     clientdbInit();
     icmpOpen();
     netdbInit();
@@ -303,6 +310,9 @@
 #ifdef SQUID_SNMP
     snmpConnectionShutdown();
 #endif
+#if USE_WCCP
+    wccpConnectionShutdown();
+#endif
     asnFreeMemory();
 }
 
@@ -320,19 +330,32 @@
 #ifdef SQUID_SNMP
     snmpConnectionClose();
 #endif
+#if USE_WCCP
+    wccpConnectionClose();
+#endif
     dnsShutdown();
+#if !USE_DNSSERVERS
+    idnsShutdown();
+#endif
     redirectShutdown();
     authenticateShutdown();
     storeDirCloseSwapLogs();
     errorClean();
+    mimeFreeMemory();
     parseConfigFile(ConfigFile);
     _db_init(Config.Log.log, Config.debugOptions);
     ipcache_restart();		/* clear stuck entries */
     fqdncache_restart();	/* sigh, fqdncache too */
     errorInitialize();		/* reload error pages */
     dnsInit();
+#if !USE_DNSSERVERS
+    idnsInit();
+#endif
     redirectInit();
     authenticateInit();
+#if USE_WCCP
+    wccpInit();
+#endif
     serverConnectionsOpen();
     if (theOutIcpConnection >= 0) {
 	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
@@ -341,6 +364,7 @@
 	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
     }
     storeDirOpenSwapLogs();
+    mimeInit(Config.mimeTablePathname);
     writePidFile();		/* write PID file */
     debug(1, 1) ("Ready to serve requests.\n");
     reconfiguring = 0;
@@ -405,6 +429,10 @@
 static void
 mainInitialize(void)
 {
+    /* chroot if configured to run inside chroot */
+    if (Config.chroot_dir && chroot(Config.chroot_dir)) {
+	fatal("failed to chroot");
+    }
     if (opt_catch_signals) {
 	squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
 	squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND);
@@ -413,9 +441,9 @@
     squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART);
 
     setEffectiveUser();
-    assert(Config.Port.http);
+    assert(Config.Sockaddr.http);
     if (httpPortNumOverride != 1)
-	Config.Port.http->i = (u_short) httpPortNumOverride;
+	Config.Sockaddr.http->s.sin_port = htons(httpPortNumOverride);
     if (icpPortNumOverride != 1)
 	Config.Port.icp = (u_short) icpPortNumOverride;
 
@@ -435,6 +463,9 @@
     ipcache_init();
     fqdncache_init();
     dnsInit();
+#if !USE_DNSSERVERS
+    idnsInit();
+#endif
     redirectInit();
     authenticateInit();
     useragentOpenLog();
@@ -448,12 +479,14 @@
 #ifdef SQUID_SNMP
     snmpInit();
 #endif
-
 #if MALLOC_DBG
     malloc_debug(0, malloc_debug_level);
 #endif
 
     if (!configured_once) {
+#if USE_ASYNC_IO
+	aioInit();
+#endif
 	unlinkdInit();
 	urlInitialize();
 	cachemgrInit();
@@ -464,13 +497,15 @@
 	do_mallinfo = 1;
 	mimeInit(Config.mimeTablePathname);
 	pconnInit();
-	eventInit();
 	refreshInit();
 #if DELAY_POOLS
 	delayPoolsInit();
 #endif
 	fwdInit();
     }
+#if USE_WCCP
+    wccpInit();
+#endif
     serverConnectionsOpen();
     if (theOutIcpConnection >= 0) {
 	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
@@ -478,6 +513,8 @@
 	else
 	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
     }
+    if (Config.chroot_dir)
+	no_suid();
     if (!configured_once)
 	writePidFile();		/* write PID file */
 
@@ -495,11 +532,10 @@
     squid_signal(SIGALRM, time_tick, SA_RESTART);
     alarm(1);
 #endif
+    memCheckInit();
     debug(1, 1) ("Ready to serve requests.\n");
-
     if (!configured_once) {
 	eventAdd("storeMaintain", storeMaintainSwapSpace, NULL, 1.0, 1);
-	eventAdd("storeDirClean", storeDirClean, NULL, 15.0, 1);
 	if (Config.onoff.announce)
 	    eventAdd("start_announce", start_announce, NULL, 3600.0, 1);
 	eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1);
@@ -514,6 +550,7 @@
     int errcount = 0;
     int n;			/* # of GC'd objects */
     time_t loop_delay;
+    mode_t oldmask;
 
     debug_log = stderr;
     if (FD_SETSIZE < Squid_MaxFD)
@@ -535,6 +572,16 @@
 #endif
 #endif /* HAVE_MALLOPT */
 
+    /*
+     * The plan here is to set the umask to 007 (deny others for
+     * read,write,execute), but only if the umask is not already
+     * set.  Unfortunately, there is no way to get the current
+     * umask value without setting it.
+     */
+    oldmask = umask(S_IRWXO);
+    if (oldmask)
+	umask(oldmask);
+
     memset(&local_addr, '\0', sizeof(struct in_addr));
     safe_inet_addr(localhost, &local_addr);
     memset(&any_addr, '\0', sizeof(struct in_addr));
@@ -561,18 +608,35 @@
 	leakInit();
 #endif
 	memInit();		/* memInit is required for config parsing */
+	eventInit();		/* eventInit() is required for config parsing */
 	parse_err = parseConfigFile(ConfigFile);
 
 	if (opt_parse_cfg_only)
 	    return parse_err;
     }
 
+#if TEST_ACCESS
+    comm_init();
+    comm_select_init();
+    mainInitialize();
+    test_access();
+    return 0;
+#endif
+
     /* send signal to running copy and exit */
     if (opt_send_signal != -1) {
+	/* chroot if configured to run inside chroot */
+	if (Config.chroot_dir && chroot(Config.chroot_dir)) {
+	    fatal("failed to chroot");
+	}
 	sendSignal();
 	/* NOTREACHED */
     }
     if (opt_create_swap_dirs) {
+	/* chroot if configured to run inside chroot */
+	if (Config.chroot_dir && chroot(Config.chroot_dir)) {
+	    fatal("failed to chroot");
+	}
 	setEffectiveUser();
 	debug(0, 0) ("Creating Swap Directories\n");
 	storeCreateSwapDirectories();
@@ -616,6 +680,9 @@
 	    shutting_down = 1;
 	    serverConnectionsClose();
 	    dnsShutdown();
+#if !USE_DNSSERVERS
+	    idnsShutdown();
+#endif
 	    redirectShutdown();
 	    authenticateShutdown();
 	    eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1);
@@ -705,9 +772,6 @@
 #endif
     for (i = 0; i < Squid_MaxFD; i++)
 	close(i);
-#if NOT_NEEDED
-    umask(0);
-#endif
     for (;;) {
 	if ((pid = fork()) == 0) {
 	    /* child */
@@ -770,6 +834,9 @@
 #ifdef SQUID_SNMP
     snmpConnectionClose();
 #endif
+#if USE_WCCP
+    wccpConnectionClose();
+#endif
     releaseServerSockets();
     commCloseAllSockets();
     unlinkdClose();
@@ -821,6 +888,7 @@
 #endif
     debug(1, 1) ("Squid Cache (Version %s): Exiting normally.\n",
 	version_string);
-    fclose(debug_log);
+    if (debug_log)
+	fclose(debug_log);
     exit(0);
 }
Index: squid/src/mem.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/mem.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/mem.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/mem.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: mem.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: mem.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 13    High Level Memory Pool Management
  * AUTHOR: Harvest Derived
@@ -65,17 +65,6 @@
 
 /* local routines */
 
-/*
- * we have a limit on _total_ amount of idle memory so we ignore
- * max_pages for now
- */
-static void
-memDataInit(mem_type type, const char *name, size_t size, int max_pages_notused)
-{
-    assert(name && size);
-    MemPools[type] = memPoolCreate(name, size);
-}
-
 static void
 memStringStats(StoreEntry * sentry)
 {
@@ -119,6 +108,17 @@
  * public routines
  */
 
+/*
+ * we have a limit on _total_ amount of idle memory so we ignore
+ * max_pages for now
+ */
+void
+memDataInit(mem_type type, const char *name, size_t size, int max_pages_notused)
+{
+    assert(name && size);
+    MemPools[type] = memPoolCreate(name, size);
+}
+
 
 /* find appropriate pool and use it (pools always init buffer with 0s) */
 void *
@@ -177,7 +177,6 @@
 memInit(void)
 {
     int i;
-    mem_type t;
     memInitModule();
     /* set all pointers to null */
     memset(MemPools, '\0', sizeof(MemPools));
@@ -291,7 +290,23 @@
 	sizeof(helper_request), 0);
     memDataInit(MEM_HELPER_SERVER, "helper_server",
 	sizeof(helper_server), 0);
-    /* test that all entries are initialized */
+    memDataInit(MEM_STORE_IO, "storeIOState", sizeof(storeIOState), 0);
+    /* init string pools */
+    for (i = 0; i < mem_str_pool_count; i++) {
+	StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
+    }
+    cachemgrRegister("mem",
+	"Memory Utilization",
+	memStats, 0, 1);
+}
+
+/*
+ * Test that all entries are initialized
+ */
+void
+memCheckInit(void)
+{
+    mem_type t;
     for (t = MEM_NONE, t++; t < MEM_MAX; t++) {
 	if (MEM_DONTFREE == t)
 	    continue;
@@ -301,17 +316,10 @@
 	 */
 	assert(MemPools[t]);
     }
-    /* init string pools */
-    for (i = 0; i < mem_str_pool_count; i++) {
-	StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
-    }
-    cachemgrRegister("mem",
-	"Memory Utilization",
-	memStats, 0, 1);
 }
 
 void
-memClean()
+memClean(void)
 {
     memCleanModule();
 }
Index: squid/src/mib.txt
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/mib.txt,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/mib.txt	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/mib.txt	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 SQUID-MIB  DEFINITIONS ::= BEGIN
 --
--- $Id: mib.txt,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+-- $Id: mib.txt,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
 --
 
 IMPORTS
Index: squid/src/mime.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/mime.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/mime.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/mime.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: mime.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: mime.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 25    MIME Parsing
  * AUTHOR: Harvest Derived
@@ -401,7 +401,7 @@
     if (storeGetPublic(url, METHOD_GET))
 	return;
     snprintf(path, MAXPATHLEN, "%s/%s", Config.icons.directory, icon);
-    fd = file_open(path, O_RDONLY, NULL, NULL, NULL);
+    fd = file_open(path, O_RDONLY);
     if (fd < 0) {
 	debug(25, 0) ("mimeLoadIconFile: %s: %s\n", path, xstrerror());
 	return;
@@ -418,6 +418,7 @@
 	METHOD_GET);
     assert(e != NULL);
     storeSetPublicKey(e);
+    storeBuffer(e);
     e->mem_obj->request = requestLink(urlParse(METHOD_GET, url));
     httpReplyReset(reply = e->mem_obj->reply);
     httpReplySetHeaders(reply, 1.0, HTTP_OK, NULL,
@@ -426,14 +427,16 @@
     httpHdrCcSetMaxAge(reply->cache_control, 86400);
     httpHeaderPutCc(&reply->header, reply->cache_control);
     httpReplySwapOut(reply, e);
+    reply->hdr_sz = e->mem_obj->inmem_hi;	/* yuk */
     /* read the file into the buffer and append it to store */
     buf = memAllocate(MEM_4K_BUF);
     while ((n = read(fd, buf, 4096)) > 0)
 	storeAppend(e, buf, n);
     file_close(fd);
+    EBIT_SET(e->flags, ENTRY_SPECIAL);
+    storeBufferFlush(e);
     storeComplete(e);
     storeTimestampsSet(e);
-    EBIT_SET(e->flags, ENTRY_SPECIAL);
     debug(25, 3) ("Loaded icon %s\n", url);
     storeUnlockObject(e);
     memFree(buf, MEM_4K_BUF);
Index: squid/src/mime.conf
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/mime.conf,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/mime.conf	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/mime.conf	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -14,8 +14,8 @@
 #
 # regexp	content-type			icon		encoding	mode
 #-----------------------------------------------------------------------------------
-\.gif$		image/gif			anthony-image.gif		-		image
-\.mime$		www/mime			anthony-text.gif	-	ascii	+download
+\.gif$			image/gif		anthony-image.gif	-	image
+\.mime$			www/mime		anthony-text.gif	-	ascii	+download
 ^internal-dirup$	-			anthony-dirup.gif	-	ascii
 ^internal-dir$		-			anthony-dir.gif		-	ascii
 ^internal-link$		-			anthony-link.gif	-	ascii
@@ -30,105 +30,106 @@
 ^internal-unknown$	-			anthony-unknown.gif	-	ascii
 ^internal-view$		-			anthony-text.gif	-	ascii
 ^internal-download$	-			anthony-box.gif		-	ascii
-\.bin$		application/macbinary		anthony-unknown.gif		-		image
-\.oda$		application/oda			anthony-unknown.gif		-		image
-\.exe$		application/octet-stream	anthony-unknown.gif		-		image
-\.pdf$		application/pdf			anthony-unknown.gif		-		image
+\.bin$		application/macbinary		anthony-unknown.gif	-	image
+\.oda$		application/oda			anthony-unknown.gif	-	image
+\.exe$		application/octet-stream	anthony-unknown.gif	-	image
+\.pdf$		application/pdf			anthony-unknown.gif	-	image
 \.ai$		application/postscript		anthony-ps.gif		-	ascii	+download
 \.eps$		application/postscript		anthony-ps.gif		-	ascii	+download
 \.ps$		application/postscript		anthony-ps.gif		-	ascii	+download +view
-\.rtf$		application/x-rtf		anthony-unknown.gif		-		image
-\.Z$		-				anthony-compressed.gif		compress	image
-\.gz$		-				anthony-unknown.gif		gzip		image
-\.tgz$		application/x-tar		anthony-tar.gif		gzip		image
-\.csh$		application/x-csh		anthony-script.gif		-		ascii
-\.dvi$		application/x-dvi		anthony-dvi.gif		-		image
-\.hdf$		application/x-hdf		anthony-unknown.gif		-		image
-\.latex$	application/x-latex		anthony-tex.gif		-		ascii
-\.lsm$		text/plain			anthony-text.gif		-		ascii
-\.nc$		application/x-netcdf		anthony-unknown.gif		-		image
+\.rtf$		application/x-rtf		anthony-unknown.gif	-	image
+\.Z$		-				anthony-compressed.gif	compress image
+\.gz$		-				anthony-unknown.gif	gzip	image
+\.tgz$		application/x-tar		anthony-tar.gif		gzip	image
+\.csh$		application/x-csh		anthony-script.gif	-	ascii
+\.dvi$		application/x-dvi		anthony-dvi.gif		-	image
+\.hdf$		application/x-hdf		anthony-unknown.gif	-	image
+\.latex$	application/x-latex		anthony-tex.gif		-	ascii
+\.lsm$		text/plain			anthony-text.gif	-	ascii
+\.nc$		application/x-netcdf		anthony-unknown.gif	-	image
 \.cdf$		application/x-netcdf		anthony-unknown.gif	-	ascii	+download
-\.sh$		application/x-sh		anthony-script.gif		-		ascii
+\.sh$		application/x-sh		anthony-script.gif	-	ascii
 \.tcl$		application/x-tcl		anthony-script.gif	-	ascii	+view
-\.tex$		application/x-tex		anthony-tex.gif		-		ascii
-\.texi$		application/x-texinfo		anthony-tex.gif		-		ascii
-\.texinfo$	application/x-texinfo		anthony-tex.gif		-		ascii
-\.t$		application/x-troff		anthony-text.gif		-		ascii
-\.roff$		application/x-troff		anthony-text.gif		-		ascii
-\.tr$		application/x-troff		anthony-text.gif		-		ascii
-\.man$		application/x-troff-man		anthony-text.gif		-		ascii
-\.me$		application/x-troff-me		anthony-text.gif		-		ascii
-\.ms$		application/x-troff-ms		anthony-text.gif		-		ascii
+\.tex$		application/x-tex		anthony-tex.gif		-	ascii
+\.texi$		application/x-texinfo		anthony-tex.gif		-	ascii
+\.texinfo$	application/x-texinfo		anthony-tex.gif		-	ascii
+\.t$		application/x-troff		anthony-text.gif	-	ascii
+\.roff$		application/x-troff		anthony-text.gif	-	ascii
+\.tr$		application/x-troff		anthony-text.gif	-	ascii
+\.man$		application/x-troff-man		anthony-text.gif	-	ascii
+\.me$		application/x-troff-me		anthony-text.gif	-	ascii
+\.ms$		application/x-troff-ms		anthony-text.gif	-	ascii
 \.src$		application/x-wais-source	anthony-text.gif	-	ascii	+download
-\.zip$		application/x-zip-compressed	anthony-compressed.gif		-		image
-\.bcpio$	application/x-bcpio		anthony-unknown.gif		-		image
-\.cpio$		application/x-cpio		anthony-unknown.gif		-		image
-\.gtar$		application/x-gtar		anthony-tar.gif		-		image
-\.rpm$		application/x-rpm		anthony-unknown.gif		-		image
-\.shar$		application/x-shar		anthony-script.gif	-	ascii	+download
-\.sv4cpio$	application/x-sv4cpio		anthony-unknown.gif		-		image
-\.sv4crc$	application/x-sv4crc		anthony-unknown.gif		-		image
-\.tar$		application/x-tar		anthony-tar.gif		-		image
-\.ustar$	application/x-ustar		anthony-tar.gif		-		image
-\.au$		audio/basic			anthony-sound.gif		-		image
-\.snd$		audio/basic			anthony-sound.gif		-		image
-\.mp2$		audio/basic			anthony-sound.gif		-		image
-\.mp3$		audio/basic			anthony-sound.gif		-		image
-\.aif$		audio/x-aiff			anthony-sound.gif		-		image
-\.aiff$		audio/x-aiff			anthony-sound.gif		-		image
-\.aifc$		audio/x-aiff			anthony-sound.gif		-		image
-\.wav$		audio/x-wav			anthony-sound.gif		-		image
-\.ief$		image/ief			anthony-image.gif		-		image
-\.jpeg$		image/jpeg			anthony-image.gif		-		image
-\.jpg$		image/jpeg			anthony-image.gif		-		image
-\.jpe$		image/jpeg			anthony-image.gif		-		image
-\.tiff$		image/tiff			anthony-image.gif		-		image
-\.tif$		image/tiff			anthony-image.gif		-		image
-\.ras$		image/cmu-raster		anthony-image.gif		-		image
-\.pnm$		image/x-portable-anymap		anthony-image.gif		-		image
-\.pbm$		image/x-portable-bitmap		anthony-image.gif		-		image
-\.pgm$		image/x-portable-graymap	anthony-image.gif		-		image
-\.ppm$		image/x-portable-pixmap		anthony-image.gif		-		image
-\.rgb$		image/x-rgb			anthony-image.gif		-		image
-\.xbm$		image/x-xbitmap			anthony-xbm.gif		-		image
-\.xpm$		image/x-xpixmap			anthony-xpm.gif		-		image
-\.xwd$		image/x-xwindowdump		anthony-image.gif		-		image
-\.html$		text/html			anthony-text.gif		-		ascii
-\.htm$		text/html			anthony-text.gif		-		ascii
-\.c$		text/plain			anthony-c.gif		-		ascii
-\.h$		text/plain			anthony-c.gif		-		ascii
-\.cc$		text/plain			anthony-c.gif		-		ascii
-\.hh$		text/plain			anthony-c.gif		-		ascii
-\.m$		text/plain			anthony-text.gif		-		ascii
-\.f90$		text/plain			anthony-text.gif		-		ascii
-\.txt$		text/plain			anthony-text.gif		-		ascii
+\.zip$		application/x-zip-compressed	anthony-compressed.gif	-	image
+\.bcpio$	application/x-bcpio		anthony-unknown.gif	-	image
+\.cpio$		application/x-cpio		anthony-unknown.gif	-	image
+\.gtar$		application/x-gtar		anthony-tar.gif		-	image
+\.rpm$		application/x-rpm		anthony-unknown.gif	-	image
+\.shar$		application/x-shar		anthony-script.gif	-	image	+download +view
+\.sv4cpio$	application/x-sv4cpio		anthony-unknown.gif	-	image
+\.sv4crc$	application/x-sv4crc		anthony-unknown.gif	-	image
+\.tar$		application/x-tar		anthony-tar.gif		-	image
+\.ustar$	application/x-ustar		anthony-tar.gif		-	image
+\.au$		audio/basic			anthony-sound.gif	-	image
+\.snd$		audio/basic			anthony-sound.gif	-	image
+\.mp2$		audio/basic			anthony-sound.gif	-	image
+\.mp3$		audio/basic			anthony-sound.gif	-	image
+\.aif$		audio/x-aiff			anthony-sound.gif	-	image
+\.aiff$		audio/x-aiff			anthony-sound.gif	-	image
+\.aifc$		audio/x-aiff			anthony-sound.gif	-	image
+\.wav$		audio/x-wav			anthony-sound.gif	-	image
+\.ief$		image/ief			anthony-image.gif	-	image
+\.jpeg$		image/jpeg			anthony-image.gif	-	image
+\.jpg$		image/jpeg			anthony-image.gif	-	image
+\.jpe$		image/jpeg			anthony-image.gif	-	image
+\.tiff$		image/tiff			anthony-image.gif	-	image
+\.tif$		image/tiff			anthony-image.gif	-	image
+\.ras$		image/cmu-raster		anthony-image.gif	-	image
+\.pnm$		image/x-portable-anymap		anthony-image.gif	-	image
+\.pbm$		image/x-portable-bitmap		anthony-image.gif	-	image
+\.pgm$		image/x-portable-graymap	anthony-image.gif	-	image
+\.ppm$		image/x-portable-pixmap		anthony-image.gif	-	image
+\.rgb$		image/x-rgb			anthony-image.gif	-	image
+\.xbm$		image/x-xbitmap			anthony-xbm.gif		-	image
+\.xpm$		image/x-xpixmap			anthony-xpm.gif		-	image
+\.xwd$		image/x-xwindowdump		anthony-image.gif	-	image
+\.html$		text/html			anthony-text.gif	-	ascii
+\.htm$		text/html			anthony-text.gif	-	ascii
+\.c$		text/plain			anthony-c.gif		-	ascii
+\.h$		text/plain			anthony-c.gif		-	ascii
+\.cc$		text/plain			anthony-c.gif		-	ascii
+\.hh$		text/plain			anthony-c.gif		-	ascii
+\.m$		text/plain			anthony-text.gif	-	ascii
+\.f90$		text/plain			anthony-text.gif	-	ascii
+\.txt$		text/plain			anthony-text.gif	-	ascii
 \.rtx$		text/richtext			anthony-text.gif	-	ascii	+download
 \.tsv$		text/tab-separated-values	anthony-text.gif	-	ascii	+download
 \.etx$		text/x-setext			anthony-text.gif	-	ascii	+download
-\.mpeg$		video/mpeg			anthony-movie.gif		-		image
-\.mpg$		video/mpeg			anthony-movie.gif		-		image
-\.mpe$		video/mpeg			anthony-movie.gif		-		image
-\.qt$		video/quicktime			anthony-movie.gif		-		image
-\.mov$		video/quicktime			anthony-movie.gif		-		image
-\.avi$		video/x-msvideo			anthony-movie.gif		-		image
-\.movie$	video/x-sgi-movie		anthony-movie.gif		-		image
-\.hqx$		application/mac-binhex40	anthony-binhex.gif		-		image
-\.mwrt$		application/macwriteii		anthony-unknown.gif		-		image
-\.msw$		application/msword		anthony-unknown.gif		-		image
+\.mpeg$		video/mpeg			anthony-movie.gif	-	image
+\.mpg$		video/mpeg			anthony-movie.gif	-	image
+\.mpe$		video/mpeg			anthony-movie.gif	-	image
+\.qt$		video/quicktime			anthony-movie.gif	-	image
+\.mov$		video/quicktime			anthony-movie.gif	-	image
+\.avi$		video/x-msvideo			anthony-movie.gif	-	image
+\.movie$	video/x-sgi-movie		anthony-movie.gif	-	image
+\.hqx$		application/mac-binhex40	anthony-binhex.gif	-	image
+\.mwrt$		application/macwriteii		anthony-unknown.gif	-	image
+\.msw$		application/msword		anthony-unknown.gif	-	image
 \.doc$		application/msword		anthony-unknown.gif	-	image	+view
 \.xls$		application/msexcel		anthony-unknown.gif	-	image
 \.wk[s1234]$	application/vnd.lotus-1-2-3	anthony-unknown.gif	-	image
-\.mif$		application/x-mif		anthony-unknown.gif		-		image
-\.sit$		application/stuffit		anthony-unknown.gif		-		image
-\.pict$		application/pict		anthony-image.gif		-		image
-\.pic$		application/pict		anthony-image.gif		-		image
-\.arj$		application/x-arj-compressed	anthony-compressed.gif		-		image
-\.lzh$		application/x-lha-compressed	anthony-compressed.gif		-		image
-\.lha$		application/x-lha-compressed	anthony-compressed.gif		-		image
-\.zlib$		application/x-deflate		anthony-compressed.gif		deflate		image
+\.mif$		application/x-mif		anthony-unknown.gif	-	image
+\.sit$		application/stuffit		anthony-unknown.gif	-	image
+\.pict$		application/pict		anthony-image.gif	-	image
+\.pic$		application/pict		anthony-image.gif	-	image
+\.arj$		application/x-arj-compressed	anthony-compressed.gif	-	image
+\.lzh$		application/x-lha-compressed	anthony-compressed.gif	-	image
+\.lha$		application/x-lha-compressed	anthony-compressed.gif	-	image
+\.zlib$		application/x-deflate		anthony-compressed.gif	deflate	image
 README		text/plain			anthony-text.gif	-	ascii	+download
-^core$		application/octet-stream	anthony-bomb.gif		-		image
-\.core$		application/octet-stream	anthony-bomb.gif		-		image
-\.png$		image/png			anthony-image.gif		-		image
+^core$		application/octet-stream	anthony-bomb.gif	-	image
+\.core$		application/octet-stream	anthony-bomb.gif	-	image
+\.png$		image/png			anthony-image.gif	-	image
+\.cab$		application/octet-stream	anthony-compressed.gif	-	image	+view
 # the default
 .		text/plain			anthony-unknown.gif	-	image	+view +download
Index: squid/src/neighbors.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/neighbors.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/neighbors.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/neighbors.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: neighbors.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: neighbors.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -102,7 +102,7 @@
 {
     const struct _domain_type *d = NULL;
     for (d = p->typelist; d; d = d->next) {
-	if (matchDomainName(d->domain, request->host))
+	if (0 == matchDomainName(request->host, d->domain))
 	    if (d->type != PEER_NONE)
 		return d->type;
     }
@@ -136,7 +136,7 @@
 	return do_ping;
     do_ping = 0;
     for (d = p->peer_domain; d; d = d->next) {
-	if (matchDomainName(d->domain, request->host)) {
+	if (0 == matchDomainName(request->host, d->domain)) {
 	    do_ping = d->do_ping;
 	    break;
 	}
@@ -148,6 +148,7 @@
 	return do_ping;
     checklist.src_addr = request->client_addr;
     checklist.my_addr = request->my_addr;
+    checklist.my_port = request->my_port;
     checklist.request = request;
     return aclCheckFast(p->access, &checklist);
 }
@@ -506,10 +507,15 @@
      */
     if (Config.Timeout.icp_query)
 	*timeout = Config.Timeout.icp_query;
-    else if (*exprep > 0)
-	(*timeout) = 2 * (*timeout) / (*exprep);
-    else
-	*timeout = 2000;	/* 2 seconds */
+    else {
+	if (*exprep > 0)
+	    (*timeout) = 2 * (*timeout) / (*exprep);
+	else
+	    *timeout = 2000;	/* 2 seconds */
+	if (Config.Timeout.icp_query_max)
+	    if (*timeout > Config.Timeout.icp_query_max)
+		*timeout = Config.Timeout.icp_query_max;
+    }
     return peers_pinged;
 }
 
@@ -1301,7 +1307,7 @@
 	neighborCountIgnored(p);
 	return;
     }
-    debug(15, 1) ("neighborsHtcpReply: e = %p\n", e);
+    debug(15, 3) ("neighborsHtcpReply: e = %p\n", e);
     mem->ping_reply_callback(p, ntype, PROTO_HTCP, htcp, mem->ircb_data);
 }
 #endif
Index: squid/src/net_db.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/net_db.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/net_db.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/net_db.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: net_db.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: net_db.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 38    Network Measurement Database
  * AUTHOR: Duane Wessels
@@ -528,7 +528,7 @@
 	    debug(38, 5) ("netdbExchangeHandleReply: hdr_sz = %d\n", hdr_sz);
 	    rep = ex->e->mem_obj->reply;
 	    if (0 == rep->sline.status)
-		httpReplyParse(rep, buf);
+		httpReplyParse(rep, buf, hdr_sz);
 	    debug(38, 3) ("netdbExchangeHandleReply: reply status %d\n",
 		rep->sline.status);
 	    if (HTTP_OK != rep->sline.status) {
@@ -973,7 +973,9 @@
     storeClientCopy(ex->e, ex->seen, ex->used, ex->buf_sz,
 	ex->buf, netdbExchangeHandleReply, ex);
     ex->r->flags.loopdetect = 1;	/* cheat! -- force direct */
-    fwdStart(-1, ex->e, ex->r, no_addr, no_addr);
+    if (p->login)
+	xstrncpy(ex->r->login, p->login, MAX_LOGIN_SZ);
+    fwdStart(-1, ex->e, ex->r);
 #endif
 }
 
Index: squid/src/peer_digest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/peer_digest.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/peer_digest.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/peer_digest.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: peer_digest.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: peer_digest.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 72    Peer Digest Routines
  * AUTHOR: Alex Rousskov
@@ -275,7 +275,12 @@
     pd->flags.requested = 1;
 
     /* compute future request components */
-    url = internalRemoteUri(p->host, p->http_port, "/squid-internal-periodic/", StoreDigestFileName);
+    if (p->digest_url)
+	url = xstrdup(p->digest_url);
+    else
+	url = internalRemoteUri(p->host, p->http_port,
+	    "/squid-internal-periodic/", StoreDigestFileName);
+
     key = storeKeyPublic(url, METHOD_GET);
     debug(72, 2) ("peerDigestRequest: %s key: %s\n", url, storeKeyText(key));
     req = urlParse(METHOD_GET, url);
@@ -285,7 +290,8 @@
     assert(!req->header.len);
     httpHeaderPutStr(&req->header, HDR_ACCEPT, StoreDigestMimeStr);
     httpHeaderPutStr(&req->header, HDR_ACCEPT, "text/html");
-
+    if (p->login)
+	xstrncpy(req->login, p->login, MAX_LOGIN_SZ);
     /* create fetch state structure */
     fetch = memAllocate(MEM_DIGEST_FETCH_STATE);
     cbdataAdd(fetch, memFree, MEM_DIGEST_FETCH_STATE);
@@ -317,7 +323,7 @@
 
     /* push towards peer cache */
     debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n");
-    fwdStart(-1, e, req, no_addr, no_addr);
+    fwdStart(-1, e, req);
     cbdataLock(fetch);
     cbdataLock(fetch->pd);
     storeClientCopy(e, 0, 0, 4096, memAllocate(MEM_4K_BUF),
@@ -330,17 +336,18 @@
 {
     DigestFetchState *fetch = data;
     PeerDigest *pd = fetch->pd;
+    size_t hdr_size;
     assert(pd && buf);
     assert(!fetch->offset);
 
     if (peerDigestFetchedEnough(fetch, buf, size, "peerDigestFetchReply"))
 	return;
 
-    if (headersEnd(buf, size)) {
+    if ((hdr_size = headersEnd(buf, size))) {
 	http_status status;
 	HttpReply *reply = fetch->entry->mem_obj->reply;
 	assert(reply);
-	httpReplyParse(reply, buf);
+	httpReplyParse(reply, buf, hdr_size);
 	status = reply->sline.status;
 	debug(72, 3) ("peerDigestFetchReply: %s status: %d, expires: %d (%+d)\n",
 	    strBuf(pd->host), status,
@@ -410,7 +417,7 @@
     if ((hdr_size = headersEnd(buf, size))) {
 	assert(fetch->entry->mem_obj->reply);
 	if (!fetch->entry->mem_obj->reply->sline.status)
-	    httpReplyParse(fetch->entry->mem_obj->reply, buf);
+	    httpReplyParse(fetch->entry->mem_obj->reply, buf, hdr_size);
 	if (fetch->entry->mem_obj->reply->sline.status != HTTP_OK) {
 	    debug(72, 1) ("peerDigestSwapInHeaders: %s status %d got cached!\n",
 		strBuf(fetch->pd->host), fetch->entry->mem_obj->reply->sline.status);
Index: squid/src/peer_select.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/peer_select.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/peer_select.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/peer_select.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: peer_select.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: peer_select.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 44    Peer Selection Algorithm
  * AUTHOR: Duane Wessels
@@ -52,7 +52,8 @@
     "SOURCE_FASTEST",
     "ROUNDROBIN_PARENT",
 #if USE_CACHE_DIGESTS
-    "CACHE_DIGEST_HIT",
+    "CD_PARENT_HIT",
+    "CD_SIBLING_HIT",
 #endif
 #if USE_CARP
     "CARP",
@@ -236,9 +237,6 @@
 	    ps->acl_checklist = aclChecklistCreate(
 		Config.accessList.AlwaysDirect,
 		request,
-		request->client_addr,
-		request->my_addr,
-		NULL,		/* user agent */
 		NULL);		/* ident */
 	    aclNBCheck(ps->acl_checklist,
 		peerCheckAlwaysDirectDone,
@@ -250,9 +248,6 @@
 	    ps->acl_checklist = aclChecklistCreate(
 		Config.accessList.NeverDirect,
 		request,
-		request->client_addr,
-		request->my_addr,
-		NULL,		/* user agent */
 		NULL);		/* ident */
 	    aclNBCheck(ps->acl_checklist,
 		peerCheckNeverDirectDone,
@@ -310,7 +305,10 @@
     }
 #if USE_CACHE_DIGESTS
     if ((p = neighborsDigestSelect(request, entry))) {
-	code = CACHE_DIGEST_HIT;
+	if (neighborType(p, request) == PEER_PARENT)
+	    code = CD_PARENT_HIT;
+	else
+	    code = CD_SIBLING_HIT;
     } else
 #endif
 #if USE_CARP
@@ -534,7 +532,6 @@
 peerHandleHtcpReply(peer * p, peer_t type, htcpReplyData * htcp, void *data)
 {
     ps_state *psstate = data;
-    request_t *request = psstate->request;
     debug(44, 3) ("peerHandleIcpReply: %s %s\n",
 	htcp->hit ? "HIT" : "MISS",
 	storeUrl(psstate->entry));
Index: squid/src/pinger.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/pinger.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/pinger.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/pinger.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: pinger.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: pinger.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 42    ICMP Pinger program
  * AUTHOR: Duane Wessels
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/protos.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/protos.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: protos.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -44,9 +44,6 @@
 
 extern aclCheck_t *aclChecklistCreate(const struct _acl_access *,
     request_t *,
-    struct in_addr src,
-    struct in_addr me,
-    const char *user_agent,
     const char *ident);
 extern void aclNBCheck(aclCheck_t *, PF *, void *);
 extern int aclCheckFast(const struct _acl_access *A, aclCheck_t *);
@@ -77,18 +74,26 @@
 extern int aio_opendir(const char *, aio_result_t *);
 extern aio_result_t *aio_poll_done(void);
 extern int aio_operations_pending(void);
-
-extern void aioCancel(int, void *);
-extern void aioOpen(const char *, int, mode_t, AIOCB *, void *, void *);
+extern int aio_overloaded(void);
+extern int aio_sync(void);
+extern int aio_get_queue_len(void);
+
+extern void aioInit(void);
+extern void aioCancel(int);
+extern void aioOpen(const char *, int, mode_t, AIOCB *, void *);
 extern void aioClose(int);
-extern void aioWrite(int, int offset, char *, int size, AIOCB *, void *);
+extern void aioWrite(int, int offset, char *, int size, AIOCB *, void *, FREE *);
 extern void aioRead(int, int offset, char *, int size, AIOCB *, void *);
-extern void aioStat(char *, struct stat *, AIOCB *, void *, void *);
+extern void aioStat(char *, struct stat *, AIOCB *, void *);
 extern void aioUnlink(const char *, AIOCB *, void *);
 extern void aioCheckCallbacks(void);
 extern void aioSync(void);
+extern int aioQueueSize(void);
 #endif
 
+/*
+ * cache_cf.c
+ */
 extern int parseConfigFile(const char *file_name);
 extern void intlistDestroy(intlist **);
 extern int intlistFind(intlist * list, int i);
@@ -97,6 +102,10 @@
 extern void wordlistDestroy(wordlist **);
 extern void configFreeMemory(void);
 extern void wordlistCat(const wordlist *, MemBuf * mb);
+extern void allocate_new_swapdir(cacheSwap *);
+extern void self_destruct(void);
+extern int GetInteger(void);
+
 
 extern void cbdataInit(void);
 #if CBDATA_DEBUG
@@ -115,6 +124,7 @@
 extern int clientdbCutoffDenied(struct in_addr);
 extern void clientdbDump(StoreEntry *);
 extern void clientdbFreeMemory(void);
+extern int clientdbEstablished(struct in_addr, int);
 
 extern void clientAccessCheck(void *);
 extern void clientAccessCheckDone(int, void *);
@@ -128,6 +138,7 @@
 extern int isTcpHit(log_type);
 
 extern int commSetNonBlocking(int fd);
+extern int commUnsetNonBlocking(int fd);
 extern void commSetCloseOnExec(int fd);
 extern int comm_accept(int fd, struct sockaddr_in *, struct sockaddr_in *);
 extern void comm_close(int fd);
@@ -200,18 +211,23 @@
 extern void debugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm);
 
 
-extern int file_open(const char *path, int mode, FOCB *, void *callback_data, void *tag);
+extern int file_open(const char *path, int mode);
 extern void file_close(int fd);
 extern void file_write(int, off_t, void *, int len, DWCB *, void *, FREE *);
 extern void file_write_mbuf(int fd, off_t, MemBuf mb, DWCB * handler, void *handler_data);
-extern int file_read(int, char *, int, off_t, DRCB *, void *);
+extern void file_read(int, char *, int, off_t, DRCB *, void *);
 extern void disk_init(void);
-extern int diskWriteIsComplete(int);
 
 extern void dnsShutdown(void);
 extern void dnsInit(void);
 extern void dnsSubmit(const char *lookup, HLPCB * callback, void *data);
 
+/* dns_internal.c */
+extern void idnsInit(void);
+extern void idnsShutdown(void);
+extern void idnsALookup(const char *, IDNSCB *, void *);
+extern void idnsPTRLookup(const struct in_addr, IDNSCB *, void *);
+
 extern void eventAdd(const char *name, EVH * func, void *arg, double when, int);
 extern void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int);
 extern void eventRun(void);
@@ -222,9 +238,6 @@
 extern int eventFind(EVH *, void *);
 
 extern void fd_close(int fd);
-#if USE_ASYNC_IO
-extern void fd_was_closed(int fd);
-#endif
 extern void fd_open(int fd, unsigned int type, const char *);
 extern void fd_note(int fd, const char *);
 extern void fd_bytes(int fd, int len, unsigned int type);
@@ -233,13 +246,12 @@
 extern int fdNFree(void);
 extern void fdAdjustReserved(void);
 
-extern fileMap *file_map_create(int);
+extern fileMap *file_map_create(void);
 extern int file_map_allocate(fileMap *, int);
 extern int file_map_bit_set(fileMap *, int);
 extern int file_map_bit_test(fileMap *, int);
 extern void file_map_bit_reset(fileMap *, int);
 extern void filemapFreeMemory(fileMap *);
-extern void filemapCopy(fileMap * old, fileMap * new);
 
 
 extern void fqdncache_nbgethostbyaddr(struct in_addr, FQDNH *, void *);
@@ -267,13 +279,13 @@
 extern void httpStart(FwdState *);
 extern void httpParseReplyHeaders(const char *, http_reply *);
 extern void httpProcessReplyHeader(HttpStateData *, const char *, int);
-extern size_t httpBuildRequestPrefix(request_t * request,
+extern mb_size_t httpBuildRequestPrefix(request_t * request,
     request_t * orig_request,
     StoreEntry * entry,
     MemBuf * mb,
     int cfd,
     http_state_flags);
-extern void httpAnonInitModule();
+extern void httpAnonInitModule(void);
 extern int httpAnonHdrAllowed(http_hdr_type hdr_id);
 extern int httpAnonHdrDenied(http_hdr_type hdr_id);
 extern void httpBuildRequestHeader(request_t *, request_t *, StoreEntry *, HttpHeader *, int, http_state_flags);
@@ -311,15 +323,16 @@
 extern void httpBodyPackInto(const HttpBody * body, Packer * p);
 
 /* Http Cache Control Header Field */
-extern void httpHdrCcInitModule();
-extern void httpHdrCcCleanModule();
-extern HttpHdrCc *httpHdrCcCreate();
+extern void httpHdrCcInitModule(void);
+extern void httpHdrCcCleanModule(void);
+extern HttpHdrCc *httpHdrCcCreate(void);
 extern HttpHdrCc *httpHdrCcParseCreate(const String * str);
 extern void httpHdrCcDestroy(HttpHdrCc * cc);
 extern HttpHdrCc *httpHdrCcDup(const HttpHdrCc * cc);
 extern void httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p);
 extern void httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc);
 extern void httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age);
+extern void httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage);
 extern void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist);
 extern void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count);
 
@@ -333,17 +346,17 @@
 /* iterate through specs */
 extern HttpHdrRangeSpec *httpHdrRangeGetSpec(const HttpHdrRange * range, HttpHdrRangePos * pos);
 /* adjust specs after the length is known */
-extern int httpHdrRangeCanonize(HttpHdrRange * range, size_t clen);
+extern int httpHdrRangeCanonize(HttpHdrRange *, ssize_t);
 /* other */
 extern String httpHdrRangeBoundaryStr(clientHttpRequest * http);
 extern int httpHdrRangeIsComplex(const HttpHdrRange * range);
 extern int httpHdrRangeWillBeComplex(const HttpHdrRange * range);
-extern size_t httpHdrRangeFirstOffset(const HttpHdrRange * range);
-extern size_t httpHdrRangeLowestOffset(const HttpHdrRange * range, size_t size);
+extern ssize_t httpHdrRangeFirstOffset(const HttpHdrRange * range);
+extern ssize_t httpHdrRangeLowestOffset(const HttpHdrRange * range, ssize_t);
 
 
 /* Http Content Range Header Field */
-extern HttpHdrContRange *httpHdrContRangeCreate();
+extern HttpHdrContRange *httpHdrContRangeCreate(void);
 extern HttpHdrContRange *httpHdrContRangeParseCreate(const char *crange_spec);
 /* returns true if range is valid; inits HttpHdrContRange */
 extern int httpHdrContRangeParseInit(HttpHdrContRange * crange, const char *crange_spec);
@@ -351,7 +364,7 @@
 extern HttpHdrContRange *httpHdrContRangeDup(const HttpHdrContRange * crange);
 extern void httpHdrContRangePackInto(const HttpHdrContRange * crange, Packer * p);
 /* inits with given spec */
-extern void httpHdrContRangeSet(HttpHdrContRange *, HttpHdrRangeSpec, size_t ent_len);
+extern void httpHdrContRangeSet(HttpHdrContRange *, HttpHdrRangeSpec, ssize_t);
 
 /* Http Header Tools */
 extern HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count);
@@ -361,26 +374,25 @@
 extern void httpHeaderMaskInit(HttpHeaderMask * mask, int value);
 extern void httpHeaderCalcMask(HttpHeaderMask * mask, const int *enums, int count);
 extern int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive);
-extern void httpHeaderAddContRange(HttpHeader * hdr, HttpHdrRangeSpec spec, size_t ent_len);
+extern void httpHeaderAddContRange(HttpHeader *, HttpHdrRangeSpec, ssize_t);
 extern void strListAdd(String * str, const char *item, char del);
 extern int strListIsMember(const String * str, const char *item, char del);
 extern int strListIsSubstr(const String * list, const char *s, char del);
 extern int strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos);
 extern const char *getStringPrefix(const char *str, const char *end);
 extern int httpHeaderParseInt(const char *start, int *val);
-extern int httpHeaderParseSize(const char *start, size_t * sz);
+extern int httpHeaderParseSize(const char *start, ssize_t * sz);
 extern int httpHeaderReset(HttpHeader * hdr);
 #if STDC_HEADERS
 extern void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...);
 #else
-extern void
-     httpHeaderPutStrf();
+extern void httpHeaderPutStrf();
 #endif
 
 
 /* Http Header */
-extern void httpHeaderInitModule();
-extern void httpHeaderCleanModule();
+extern void httpHeaderInitModule(void);
+extern void httpHeaderCleanModule(void);
 /* init/clean */
 extern void httpHeaderInit(HttpHeader * hdr, http_hdr_owner_type owner);
 extern void httpHeaderClean(HttpHeader * hdr);
@@ -428,16 +440,16 @@
 extern int httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end);
 
 /* Http Reply */
-extern void httpReplyInitModule();
+extern void httpReplyInitModule(void);
 /* create/destroy */
-extern HttpReply *httpReplyCreate();
+extern HttpReply *httpReplyCreate(void);
 extern void httpReplyDestroy(HttpReply * rep);
 /* reset: clean, then init */
 extern void httpReplyReset(HttpReply * rep);
 /* absorb: copy the contents of a new reply to the old one, destroy new one */
 extern void httpReplyAbsorb(HttpReply * rep, HttpReply * new_rep);
 /* parse returns -1,0,+1 on error,need-more-data,success */
-extern int httpReplyParse(HttpReply * rep, const char *buf);	/*, int atEnd); */
+extern int httpReplyParse(HttpReply * rep, const char *buf, ssize_t);
 extern void httpReplyPackInto(const HttpReply * rep, Packer * p);
 /* ez-routines */
 /* mem-pack: returns a ready to use mem buffer with a packed reply */
@@ -460,6 +472,7 @@
 extern time_t httpReplyExpires(const HttpReply * rep);
 extern int httpReplyHasCc(const HttpReply * rep, http_hdr_cc_type type);
 extern void httpRedirectReply(HttpReply *, http_status, const char *);
+extern int httpReplyBodySize(method_t, HttpReply *);
 
 /* Http Request */
 extern request_t *requestCreate(method_t, protocol_t, const char *urlpath);
@@ -471,6 +484,7 @@
 extern void httpRequestPack(const request_t * req, Packer * p);
 extern int httpRequestPrefixLen(const request_t * req);
 extern int httpRequestHdrAllowed(const HttpHeaderEntry * e, String * strConnection);
+extern int httpRequestHdrAllowedByName(http_hdr_type id);
 
 extern void icmpOpen(void);
 extern void icmpClose(void);
@@ -511,6 +525,13 @@
 extern variable_list *snmp_meshCtblFn(variable_list *, snint *);
 #endif /* SQUID_SNMP */
 
+#if USE_WCCP
+extern void wccpInit(void);
+extern void wccpConnectionOpen(void);
+extern void wccpConnectionShutdown(void);
+extern void wccpConnectionClose(void);
+#endif /* USE_WCCP */
+
 extern void icpHandleIcpV3(int, struct sockaddr_in, char *, int);
 extern int icpCheckUdpHit(StoreEntry *, request_t * request);
 extern void icpConnectionsOpen(void);
@@ -654,7 +675,7 @@
 extern void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e);
 
 /* forward.c */
-extern void fwdStart(int, StoreEntry *, request_t *, struct in_addr, struct in_addr);
+extern void fwdStart(int, StoreEntry *, request_t *);
 extern DEFER fwdCheckDeferRead;
 extern void fwdFail(FwdState *, ErrorState *);
 extern void fwdUnregister(int fd, FwdState *);
@@ -677,6 +698,7 @@
 extern int refreshIsCachable(const StoreEntry *);
 extern int refreshCheckHTTP(const StoreEntry *, request_t *);
 extern int refreshCheckICP(const StoreEntry *, request_t *);
+extern int refreshCheckHTCP(const StoreEntry *, request_t *);
 extern int refreshCheckDigest(const StoreEntry *, time_t delta);
 extern time_t getMaxAge(const char *url);
 extern void refreshInit(void);
@@ -731,10 +753,10 @@
 
 /* mem */
 extern void memInit(void);
-extern void memClean();
-extern void memInitModule();
-extern void memCleanModule();
-extern void memConfigure();
+extern void memClean(void);
+extern void memInitModule(void);
+extern void memCleanModule(void);
+extern void memConfigure(void);
 extern void *memAllocate(mem_type);
 extern void *memAllocBuf(size_t net_size, size_t * gross_size);
 extern CBDUNL memFree;
@@ -745,6 +767,8 @@
 extern void memFreeDISK(void *);
 extern int memInUse(mem_type);
 extern size_t memTotalAllocated(void);
+extern void memDataInit(mem_type, const char *, size_t, int);
+extern void memCheckInit(void);
 
 /* MemPool */
 extern MemPool *memPoolCreate(const char *label, size_t obj_size);
@@ -782,7 +806,6 @@
 extern void storeAbort(StoreEntry *);
 extern void storeAppend(StoreEntry *, const char *, int);
 extern void storeLockObject(StoreEntry *);
-extern void storeSwapInStart(StoreEntry *, SIH *, void *data);
 extern void storeRelease(StoreEntry *);
 extern int storeUnlockObject(StoreEntry *);
 extern int storeUnregister(StoreEntry *, void *);
@@ -806,11 +829,13 @@
 extern void InvokeHandlers(StoreEntry *);
 extern int storeEntryValidToSend(StoreEntry *);
 extern void storeTimestampsSet(StoreEntry *);
+#if !HEAP_REPLACEMENT
 extern time_t storeExpiredReferenceAge(void);
+#endif
 extern void storeRegisterAbort(StoreEntry * e, STABH * cb, void *);
 extern void storeUnregisterAbort(StoreEntry * e);
 extern void storeMemObjectDump(MemObject * mem);
-extern void storeEntryDump(StoreEntry * e, int debug_lvl);
+extern void storeEntryDump(const StoreEntry * e, int debug_lvl);
 extern const char *storeUrl(const StoreEntry *);
 extern void storeCreateMemObject(StoreEntry *, const char *, const char *);
 extern void storeCopyNotModifiedReplyHeaders(MemObject * O, MemObject * N);
@@ -825,13 +850,41 @@
 #endif
 extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
 extern int storeCheckCachable(StoreEntry * e);
-extern void storeUnlinkFileno(int fileno);
 extern void storeSetPrivateKey(StoreEntry *);
 extern int objectLen(const StoreEntry * e);
 extern int contentLen(const StoreEntry * e);
 extern HttpReply *storeEntryReply(StoreEntry *);
 extern int storeTooManyDiskFilesOpen(void);
 extern void storeEntryReset(StoreEntry *);
+extern void storeHeapPositionUpdate(StoreEntry *);
+
+/* store_io.c */
+extern STOBJOPEN storeOpen;
+extern STOBJCLOSE storeClose;
+extern STOBJREAD storeRead;
+extern STOBJWRITE storeWrite;
+extern STOBJUNLINK storeUnlink;
+extern off_t storeOffset(storeIOState *);
+
+/*
+ * store_io_ufs.c
+ */
+extern storeIOState *storeUfsOpen(sfileno, mode_t, STIOCB *, void *);
+extern void storeUfsClose(storeIOState * sio);
+extern void storeUfsRead(storeIOState *, char *, size_t, off_t, STRCB *, void *);
+extern void storeUfsWrite(storeIOState *, char *, size_t, off_t, FREE *);
+extern void storeUfsUnlink(int fileno);
+
+#if USE_ASYNC_IO
+/*
+ * store_io_ufs.c
+ */
+extern storeIOState *storeAufsOpen(sfileno, mode_t, STIOCB *, void *);
+extern void storeAufsClose(storeIOState * sio);
+extern void storeAufsRead(storeIOState *, char *, size_t, off_t, STRCB *, void *);
+extern void storeAufsWrite(storeIOState *, char *, size_t, off_t, FREE *);
+extern void storeAufsUnlink(int fileno);
+#endif
 
 /*
  * store_log.c
@@ -859,47 +912,54 @@
 extern HASHCMP storeKeyHashCmp;
 
 /*
- * store_clean.c
+ * store_digest.c
  */
-extern EVH storeDirClean;
-
-/* store_digest.c */
-extern void storeDigestInit();
-extern void storeDigestNoteStoreReady();
-extern void storeDigestScheduleRebuild();
+extern void storeDigestInit(void);
+extern void storeDigestNoteStoreReady(void);
+extern void storeDigestScheduleRebuild(void);
 extern void storeDigestDel(const StoreEntry * entry);
-extern void storeDigestReport();
+extern void storeDigestReport(StoreEntry *);
 
 /*
  * store_dir.c
  */
+extern OBJH storeDirStats;
+extern char *storeDirSwapLogFile(int, const char *);
+extern char *storeSwapDir(int);
 extern char *storeSwapFullPath(int, char *);
 extern char *storeSwapSubSubDir(int, char *);
-extern int storeVerifySwapDirs(void);
 extern const char *storeSwapPath(int);
-extern int storeDirMapBitTest(int fn);
-extern void storeDirMapBitSet(int fn);
-extern void storeDirMapBitReset(int fn);
 extern int storeDirMapAllocate(void);
-extern char *storeSwapDir(int);
-extern FILE *storeDirOpenTmpSwapLog(int dirn, int *clean, int *zero);
-extern void storeDirCloseTmpSwapLog(int dirn);
-extern void storeDirOpenSwapLogs(void);
-extern void storeDirCloseSwapLogs(void);
-extern char *storeDirSwapLogFile(int, const char *);
-extern void storeDirSwapLog(const StoreEntry *, int op);
+extern int storeDirMapBitTest(int fn);
+extern int storeDirMapBitsInUse(void);
 extern int storeDirNumber(int fileno);
-extern void storeDirUpdateSwapSize(int fn, size_t size, int sign);
 extern int storeDirProperFileno(int dirn, int fn);
-extern void storeCreateSwapDirectories(void);
-extern int storeVerifyCacheDirs(void);
+extern int storeDirValidFileno(int fn, int);
 extern int storeDirWriteCleanLogs(int reopen);
-extern int storeDirValidFileno(int fn);
-extern int storeFilenoBelongsHere(int, int, int, int);
-extern OBJH storeDirStats;
-extern int storeDirMapBitsInUse(void);
+extern int storeVerifySwapDirs(void);
+extern void storeCreateSwapDirectories(void);
+extern void storeDirCloseSwapLogs(void);
+extern void storeDirCloseTmpSwapLog(int dirn);
 extern void storeDirConfigure(void);
 extern void storeDirDiskFull(int fn);
+extern void storeDirInit(void);
+extern void storeDirMapBitReset(int fn);
+extern void storeDirMapBitSet(int fn);
+extern void storeDirOpenSwapLogs(void);
+extern void storeDirSwapLog(const StoreEntry *, int op);
+extern void storeDirUpdateSwapSize(int fn, size_t size, int sign);
+
+/*
+ * store_dir_ufs.c
+ */
+extern OBJH storeUfsDirStats;
+extern void storeUfsDirParse(cacheSwap * swap);
+extern void storeUfsDirDump(StoreEntry * entry, const char *name, SwapDir * s);
+extern void storeUfsDirFree(SwapDir *);
+extern char *storeUfsFullPath(sfileno fn, char *fullpath);
+#if USE_ASYNC_IO
+extern void storeAufsDirParse(cacheSwap * swap);
+#endif
 
 
 /*
@@ -913,23 +973,19 @@
 /*
  * store_rebuild.c
  */
-extern void storeDoRebuildFromSwapFiles(void *data);
-extern void storeValidate(StoreEntry *, STVLDCB *, void *, void *);
 extern void storeRebuildStart(void);
+extern void storeRebuildComplete(struct _store_rebuild_data *);
 
 /*
  * store_swapin.c
  */
-extern void storeSwapInStart(StoreEntry * e, SIH * callback, void *callback_data);
-extern void storeSwapInValidateComplete(void *data, int retcode, int errcode);
-extern void storeSwapInFileOpened(void *data, int fd, int errcode);
+extern void storeSwapInStart(store_client *);
 
 /*
  * store_swapout.c
  */
-extern void storeCheckSwapOut(StoreEntry * e);
+extern void storeSwapOut(StoreEntry * e);
 extern void storeSwapOutFileClose(StoreEntry * e);
-extern int storeSwapOutWriteQueued(MemObject * mem);
 extern int storeSwapOutAble(const StoreEntry * e);
 
 /*
@@ -1001,7 +1057,7 @@
 extern const char *urlCanonical(request_t *);
 extern char *urlRInternal(const char *host, u_short port, const char *dir, const char *name);
 extern char *urlInternal(const char *dir, const char *name);
-extern int matchDomainName(const char *d, const char *h);
+extern int matchDomainName(const char *host, const char *domain);
 extern int urlCheckRequest(const request_t *);
 extern int urlDefaultPort(protocol_t p);
 extern char *urlCanonicalClean(const request_t *);
@@ -1038,6 +1094,10 @@
 extern const char *gb_to_str(const gb_t *);
 extern void gb_flush(gb_t *);	/* internal, do not use this */
 extern int stringHasWhitespace(const char *);
+extern int stringHasCntl(const char *);
+extern void linklistPush(link_list **, void *);
+extern void *linklistShift(link_list **);
+extern int xrename(const char *from, const char *to);
 
 #if USE_HTCP
 extern void htcpInit(void);
@@ -1099,6 +1159,7 @@
 extern char *internalLocalUri(const char *dir, const char *name);
 extern char *internalRemoteUri(const char *, u_short, const char *, const char *);
 extern const char *internalHostname(void);
+extern int internalHostnameIs(const char *);
 
 #if USE_CARP
 extern void carpInit(void);
@@ -1108,11 +1169,11 @@
 #if DELAY_POOLS
 extern void delayPoolsInit(void);
 extern void delayInitDelayData(unsigned short pools);
-extern void delayFreeDelayData();
+extern void delayFreeDelayData(void);
 extern void delayCreateDelayPool(unsigned short pool, u_char class);
 extern void delayInitDelayPool(unsigned short pool, u_char class, delaySpecSet * rates);
 extern void delayFreeDelayPool(unsigned short pool);
-extern void delayPoolsReconfigure();
+extern void delayPoolsReconfigure(void);
 extern void delaySetNoDelay(int fd);
 extern void delayClearNoDelay(int fd);
 extern int delayIsNoDelay(int fd);
Index: squid/src/pump.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/pump.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/pump.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/pump.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: pump.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: pump.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 61    PUMP handler
  * AUTHOR: Kostas Anagnostakis
@@ -43,7 +43,6 @@
     int s_fd;			/* server end */
     int rcvd;			/* bytes received from client */
     int sent;			/* bytes sent to server */
-    int cont_len;		/* Content-Length header */
     StoreEntry *request_entry;	/* the request entry */
     StoreEntry *reply_entry;	/* the reply entry */
     CWCB *callback;		/* what to do when we finish sending */
@@ -74,7 +73,6 @@
 {
     request_flags flags;
     LOCAL_ARRAY(char, new_key, MAX_URL + 8);
-    int clen = 0;
     PumpStateData *p = xcalloc(1, sizeof(PumpStateData));
     debug(61, 3) ("pumpInit: FD %d, uri=%s\n", fd, uri);
     /*
@@ -84,15 +82,16 @@
     assert(fd > -1);
     assert(uri != NULL);
     assert(r != NULL);
-    clen = httpHeaderGetInt(&r->header, HDR_CONTENT_LENGTH);
     /* we shouldn't have gotten this far if content-length is invalid */
-    assert(clen >= 0);
-    debug(61, 4) ("pumpInit: Content-Length=%d.\n", clen);
+    assert(r->content_length >= 0);
+    debug(61, 4) ("pumpInit: Content-Length=%d.\n", r->content_length);
     flags = null_request_flags;
     flags.nocache = 1;
     snprintf(new_key, MAX_URL + 5, "%s|Pump", uri);
+    cbdataAdd(p, cbdataXfree, 0);
     p->request_entry = storeCreateEntry(new_key, new_key, flags, r->method);
     storeClientListAdd(p->request_entry, p);
+    EBIT_SET(p->request_entry->flags, ENTRY_DONT_LOG);
 #if DELAY_POOLS
     delaySetStoreClient(p->request_entry, p, delayClient(r));
 #endif
@@ -101,13 +100,11 @@
      */
     p->c_fd = fd;
     p->s_fd = -1;
-    p->cont_len = clen;
     p->req = requestLink(r);
     p->callback = NULL;
     p->cbdata = NULL;
     p->next = pump_head;
     pump_head = p;
-    cbdataAdd(p, cbdataXfree, 0);
     comm_add_close_handler(p->c_fd, pumpFree, p);
     commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
     debug(61, 4) ("pumpInit: FD %d, Created %p\n", fd, p);
@@ -143,11 +140,11 @@
     /*
      * see if part of the body is in the request
      */
-    if (p->rcvd < p->cont_len && r->body_sz > 0) {
+    if (p->rcvd < p->req->content_length && r->body_sz > 0) {
 	assert(p->request_entry->store_status == STORE_PENDING);
 	assert(r->body != NULL);
-	assert(r->body_sz <= p->cont_len);
-	copy_sz = XMIN(r->body_sz, p->cont_len);
+	assert(r->body_sz <= p->req->content_length);
+	copy_sz = XMIN(r->body_sz, p->req->content_length);
 	debug(61, 3) ("pumpStart: Appending %d bytes from r->body\n", copy_sz);
 	storeAppend(p->request_entry, r->body, copy_sz);
 	p->rcvd = copy_sz;
@@ -155,14 +152,14 @@
     /*
      * Do we need to read more data from the client?
      */
-    if (p->rcvd < p->cont_len) {
+    if (p->rcvd < p->req->content_length) {
 	assert(p->request_entry->store_status == STORE_PENDING);
 	commSetSelect(p->c_fd, COMM_SELECT_READ, pumpReadFromClient, p, 0);
 	commSetTimeout(p->c_fd, Config.Timeout.read, pumpTimeout, p);
 	commSetDefer(p->c_fd, pumpReadDefer, p);
     }
     p->sent = 0;
-    if (p->sent == p->cont_len) {
+    if (p->sent == p->req->content_length) {
 	pumpServerCopyComplete(p->s_fd, NULL, 0, DISK_OK, p);
     } else {
 	storeClientCopy(p->request_entry, p->sent, p->sent, 4096,
@@ -197,7 +194,7 @@
     PumpStateData *p = data;
     int sfd;
     debug(61, 5) ("pumpServerCopyComplete: called with size=%d (%d,%d)\n",
-	size, p->sent + size, p->cont_len);
+	size, p->sent + size, p->req->content_length);
     if (errflag == COMM_ERR_CLOSING)
 	return;
     if (errflag != 0) {
@@ -211,8 +208,8 @@
 	return;
     }
     p->sent += size;
-    assert(p->sent <= p->cont_len);
-    if (p->sent < p->cont_len) {
+    assert(p->sent <= p->req->content_length);
+    if (p->sent < p->req->content_length) {
 	storeClientCopy(p->request_entry, p->sent, p->sent, 4096,
 	    memAllocate(MEM_4K_BUF),
 	    pumpServerCopy, p);
@@ -239,7 +236,7 @@
     PumpStateData *p = data;
     StoreEntry *req = p->request_entry;
     LOCAL_ARRAY(char, buf, SQUID_TCP_SO_RCVBUF);
-    int bytes_to_read = XMIN(p->cont_len - p->rcvd, SQUID_TCP_SO_RCVBUF);
+    int bytes_to_read = XMIN(p->req->content_length - p->rcvd, SQUID_TCP_SO_RCVBUF);
     int len = 0;
     errno = 0;
     Counter.syscalls.sock.reads++;
@@ -268,21 +265,21 @@
 	debug(61, 2) ("pumpReadFromClient: FD %d: failed.\n", fd);
 	pumpClose(p);
 	return;
-    } else if (p->rcvd < p->cont_len) {
+    } else if (p->rcvd < p->req->content_length) {
 	debug(61, 4) ("pumpReadFromClient: FD %d, incomplete request\n", fd);
 	pumpClose(p);
 	return;
     }
     if (len > 0) {
-	int delta = p->rcvd + len - p->cont_len;
+	int delta = p->rcvd + len - p->req->content_length;
 	if (delta > 0 && p->req->flags.proxy_keepalive) {
 	    debug(61, delta == 2 ? 3 : 1) ("pumpReadFromClient: Warning: read %d bytes past content-length, truncating\n", delta);
-	    len = p->cont_len - p->rcvd;
+	    len = p->req->content_length - p->rcvd;
 	}
 	storeAppend(req, buf, len);
 	p->rcvd += len;
     }
-    if (p->rcvd < p->cont_len) {
+    if (p->rcvd < p->req->content_length) {
 	/* We need more data */
 	commSetSelect(fd, COMM_SELECT_READ, pumpReadFromClient,
 	    p, Config.Timeout.read);
@@ -290,7 +287,7 @@
     }
     /* all done! */
     if (p->req->flags.proxy_keepalive)
-	assert(p->rcvd == p->cont_len);
+	assert(p->rcvd == p->req->content_length);
     debug(61, 2) ("pumpReadFromClient: finished!\n");
     storeComplete(req);
     commSetDefer(p->c_fd, NULL, NULL);
@@ -408,25 +405,6 @@
 }
 
 /*
- * This function returns true for the request methods handled
- * by this module
- */
-int
-pumpMethod(method_t method)
-{
-    switch (method) {
-    case METHOD_POST:
-    case METHOD_PUT:
-	return 1;
-	break;
-    default:
-	return 0;
-	break;
-    }
-    /* NOTREACHED */
-}
-
-/*
  * This function returns True if we can submit this request again.
  * The request may have been pipelined, but the connection got
  * closed before we got a reply.  If we still have the whole
Index: squid/src/redirect.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/redirect.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/redirect.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/redirect.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: redirect.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: redirect.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 29    Redirector
  * AUTHOR: Duane Wessels
@@ -48,6 +48,7 @@
 static void redirectStateFree(redirectStateData * r);
 static helper *redirectors = NULL;
 static OBJH redirectStats;
+static int n_bypassed = 0;
 
 static void
 redirectHandleReply(void *data, char *reply)
@@ -81,6 +82,9 @@
 {
     storeAppendPrintf(sentry, "Redirector Statistics:\n");
     helperStats(sentry, redirectors);
+    if (Config.onoff.redirector_bypass)
+	storeAppendPrintf(sentry, "\nNumber of requests bypassed "
+	    "because all redirectors were busy: %d\n", n_bypassed);
 }
 
 /**** PUBLIC FUNCTIONS ****/
@@ -99,11 +103,31 @@
 	handler(data, NULL);
 	return;
     }
+    if (Config.accessList.redirector) {
+	aclCheck_t ch;
+	memset(&ch, '\0', sizeof(ch));
+	ch.src_addr = http->conn->peer.sin_addr;
+	ch.my_addr = http->conn->me.sin_addr;
+	ch.request = http->request;
+	if (!aclCheckFast(Config.accessList.redirector, &ch)) {
+	    /* denied -- bypass redirector */
+	    handler(data, NULL);
+	    return;
+	}
+    }
+    if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) {
+	/* Skip redirector if there is one request queued */
+	n_bypassed++;
+	handler(data, NULL);
+	return;
+    }
     r = xcalloc(1, sizeof(redirectStateData));
     cbdataAdd(r, cbdataXfree, 0);
     r->orig_url = xstrdup(http->uri);
     r->client_addr = conn->log_addr;
-    if (conn->ident == NULL || *conn->ident == '\0') {
+    if (http->request->user_ident[0])
+	r->client_ident = http->request->user_ident;
+    else if (conn->ident == NULL || *conn->ident == '\0') {
 	r->client_ident = dash_str;
     } else {
 	r->client_ident = conn->ident;
@@ -131,7 +155,7 @@
 	return;
     if (redirectors == NULL)
 	redirectors = helperCreate("redirector");
-    wordlistAdd(&redirectors->cmdline, Config.Program.redirect);
+    redirectors->cmdline = Config.Program.redirect;
     redirectors->n_to_start = Config.redirectChildren;
     redirectors->ipc_type = IPC_TCP_SOCKET;
     helperOpenServers(redirectors);
@@ -139,8 +163,8 @@
 	cachemgrRegister("redirector",
 	    "URL Redirector Stats",
 	    redirectStats, 0, 1);
+	init = 1;
     }
-    init++;
 }
 
 void
@@ -149,7 +173,6 @@
     if (!redirectors)
 	return;
     helperShutdown(redirectors);
-    wordlistDestroy(&redirectors->cmdline);
     if (!shutting_down)
 	return;
     helperFree(redirectors);
Index: squid/src/refresh.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/refresh.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/refresh.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/refresh.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: refresh.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: refresh.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 22    Refresh Calculation
  * AUTHOR: Harvest Derived
@@ -41,7 +41,7 @@
 #include "squid.h"
 
 typedef enum {
-    rcHTTP, rcICP, rcCDigest, rcStore, rcCount
+    rcHTTP, rcICP, rcHTCP, rcCDigest, rcStore, rcCount
 } refreshCountsEnum;
 
 static struct RefreshCounts {
@@ -299,6 +299,12 @@
 }
 
 int
+refreshCheckHTCP(const StoreEntry * entry, request_t * request)
+{
+    return refreshCheck(entry, request, 10, &refreshCounts[rcHTCP]);
+}
+
+int
 refreshCheckDigest(const StoreEntry * entry, time_t delta)
 {
     return refreshCheck(entry,
@@ -328,7 +334,6 @@
     storeAppendPrintf(sentry, "Category\tCount\t%%Total\n");
 
 #define refreshCountsStatsEntry(name) { \
-    if (rc->name || !strcmp(#name, "total")) \
 	storeAppendPrintf(sentry, "%s\t%6d\t%6.2f\n", \
 	    #name, rc->name, xpercent(rc->name, tot)); \
     sum += rc->name; \
@@ -350,6 +355,7 @@
     tot = sum;			/* paranoid: "total" line shows 100% if we forgot nothing */
     refreshCountsStatsEntry(total);
     /* maybe counters */
+    storeAppendPrintf(sentry, "\n");
     refreshCountsStatsEntry(request_reload_ignore_maybe);
     refreshCountsStatsEntry(response_lmt_future_maybe);
 }
@@ -380,11 +386,12 @@
 }
 
 void
-refreshInit()
+refreshInit(void)
 {
     memset(refreshCounts, 0, sizeof(refreshCounts));
     refreshCounts[rcHTTP].proto = "HTTP";
     refreshCounts[rcICP].proto = "ICP";
+    refreshCounts[rcHTCP].proto = "HTCP";
     refreshCounts[rcStore].proto = "On Store";
     refreshCounts[rcCDigest].proto = "Cache Digests";
 
Index: squid/src/send-announce.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/send-announce.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/send-announce.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/send-announce.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: send-announce.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: send-announce.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 27    Cache Announcer
  * AUTHOR: Duane Wessels
@@ -72,10 +72,10 @@
     sndbuf[0] = '\0';
     snprintf(tbuf, 256, "cache_version SQUID/%s\n", version_string);
     strcat(sndbuf, tbuf);
-    assert(Config.Port.http);
+    assert(Config.Sockaddr.http);
     snprintf(tbuf, 256, "Running on %s %d %d\n",
 	getMyHostname(),
-	(int) Config.Port.http->i,
+	(int) ntohs(Config.Sockaddr.http->s.sin_port),
 	(int) Config.Port.icp);
     strcat(sndbuf, tbuf);
     if (Config.adminEmail) {
@@ -88,7 +88,7 @@
     strcat(sndbuf, tbuf);
     l = strlen(sndbuf);
     if ((file = Config.Announce.file) != NULL) {
-	fd = file_open(file, O_RDONLY, NULL, NULL, NULL);
+	fd = file_open(file, O_RDONLY);
 	if (fd > -1 && (n = read(fd, sndbuf + l, BUFSIZ - l - 1)) > 0) {
 	    fd_bytes(fd, n, FD_READ);
 	    l += n;
Index: squid/src/snmp_agent.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/snmp_agent.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/snmp_agent.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/snmp_agent.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: snmp_agent.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: snmp_agent.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 49     SNMP Interface
  * AUTHOR: Kostas Anagnostakis
@@ -48,37 +48,29 @@
 variable_list *
 snmp_sysFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
-
+    variable_list *Answer = NULL;
     debug(49, 5) ("snmp_sysFn: Processing request:\n", Var->name[LEN_SQ_SYS]);
     snmpDebugOid(5, Var->name, Var->name_length);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-
     switch (Var->name[LEN_SQ_SYS]) {
     case SYSVMSIZ:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = store_mem_size >> 10;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    store_mem_size >> 10,
+	    ASN_INTEGER);
 	break;
     case SYSSTOR:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = store_swap_size;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    store_swap_size,
+	    ASN_INTEGER);
 	break;
     case SYS_UPTIME:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_TIMETICKS;
-	*(Answer->val.integer) = tvSubDsec(squid_start, current_time) * 100;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    tvSubDsec(squid_start, current_time) * 100,
+	    SMI_TIMETICKS);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
@@ -86,64 +78,58 @@
 variable_list *
 snmp_confFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     char *cp = NULL;
-    char *pp = NULL;
     debug(49, 5) ("snmp_confFn: Processing request with magic %d!\n", Var->name[8]);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-
     switch (Var->name[LEN_SQ_CONF]) {
     case CONF_ADMIN:
+	Answer = snmp_var_new(Var->name, Var->name_length);
 	Answer->type = ASN_OCTET_STR;
 	Answer->val_len = strlen(Config.adminEmail);
 	Answer->val.string = (u_char *) xstrdup(Config.adminEmail);
 	break;
     case CONF_VERSION:
+	Answer = snmp_var_new(Var->name, Var->name_length);
 	Answer->type = ASN_OCTET_STR;
 	Answer->val_len = strlen(appname);
 	Answer->val.string = (u_char *) xstrdup(appname);
 	break;
     case CONF_VERSION_ID:
-	pp = SQUID_VERSION;
+	Answer = snmp_var_new(Var->name, Var->name_length);
 	Answer->type = ASN_OCTET_STR;
-	Answer->val_len = strlen(pp);
-	Answer->val.string = (u_char *) xstrdup(pp);
+	Answer->val_len = strlen(SQUID_VERSION);
+	Answer->val.string = (u_char *) xstrdup(SQUID_VERSION);
 	break;
     case CONF_STORAGE:
 	switch (Var->name[LEN_SQ_CONF + 1]) {
 	case CONF_ST_MMAXSZ:
-	    Answer->val_len = sizeof(snint);
-	    Answer->val.integer = xmalloc(Answer->val_len);
-	    Answer->type = ASN_INTEGER;
-	    *(Answer->val.integer) = (snint) Config.memMaxSize >> 20;
+	    snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Config.memMaxSize >> 20,
+		ASN_INTEGER);
 	    break;
 	case CONF_ST_SWMAXSZ:
-	    Answer->val_len = sizeof(snint);
-	    Answer->val.integer = xmalloc(Answer->val_len);
-	    Answer->type = ASN_INTEGER;
-	    *(Answer->val.integer) = (snint) Config.Swap.maxSize >> 10;
+	    snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Config.Swap.maxSize >> 10,
+		ASN_INTEGER);
 	    break;
 	case CONF_ST_SWHIWM:
-	    Answer->val_len = sizeof(snint);
-	    Answer->val.integer = xmalloc(Answer->val_len);
-	    Answer->type = ASN_INTEGER;
-	    *(Answer->val.integer) = (snint) Config.Swap.highWaterMark;
+	    snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Config.Swap.highWaterMark,
+		ASN_INTEGER);
 	    break;
 	case CONF_ST_SWLOWM:
-	    Answer->val_len = sizeof(snint);
-	    Answer->val.integer = xmalloc(Answer->val_len);
-	    Answer->type = ASN_INTEGER;
-	    *(Answer->val.integer) = (snint) Config.Swap.lowWaterMark;
+	    snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Config.Swap.lowWaterMark,
+		ASN_INTEGER);
 	    break;
 	default:
 	    *ErrP = SNMP_ERR_NOSUCHNAME;
-	    snmp_var_free(Answer);
-	    return (NULL);
+	    break;
 	}
 	break;
     case CONF_LOG_FAC:
+	Answer = snmp_var_new(Var->name, Var->name_length);
 	if (!(cp = Config.debugOptions))
 	    cp = "None";
 	Answer->type = ASN_OCTET_STR;
@@ -152,8 +138,7 @@
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
@@ -161,111 +146,92 @@
 variable_list *
 snmp_meshPtblFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     struct in_addr *laddr;
     char *cp = NULL;
     peer *p = NULL;
     int cnt = 0;
     debug(49, 5) ("snmp_meshPtblFn: peer %d requested!\n", Var->name[LEN_SQ_MESH + 3]);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-
     laddr = oid2addr(&Var->name[LEN_SQ_MESH + 3]);
-
     for (p = Config.peers; p != NULL; p = p->next, cnt++)
 	if (p->in_addr.sin_addr.s_addr == laddr->s_addr)
 	    break;
-
     if (p == NULL) {
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	return NULL;
     }
     switch (Var->name[LEN_SQ_MESH + 2]) {
     case MESH_PTBL_NAME:
 	cp = p->host;
+	Answer = snmp_var_new(Var->name, Var->name_length);
 	Answer->type = ASN_OCTET_STR;
 	Answer->val_len = strlen(cp);
 	Answer->val.string = (u_char *) xstrdup(cp);
 	break;
     case MESH_PTBL_IP:
-	Answer->type = SMI_IPADDRESS;
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	*(Answer->val.integer) = (snint) (p->in_addr.sin_addr.s_addr);
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) p->in_addr.sin_addr.s_addr,
+	    SMI_IPADDRESS);
 	break;
     case MESH_PTBL_HTTP:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = (snint) p->http_port;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) p->http_port,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_ICP:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = (snint) p->icp.port;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) p->icp.port,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_TYPE:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = (snint) p->type;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) p->type,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_STATE:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = (snint) neighborUp(p);
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) neighborUp(p),
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_SENT:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.pings_sent;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.pings_sent,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_PACKED:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.pings_acked;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.pings_acked,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_FETCHES:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.fetches;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.fetches,
+	    SMI_COUNTER32);
 	break;
     case MESH_PTBL_RTT:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = ASN_INTEGER;
-	*(Answer->val.integer) = p->stats.rtt;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.rtt,
+	    ASN_INTEGER);
 	break;
     case MESH_PTBL_IGN:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.ignored_replies;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.ignored_replies,
+	    SMI_COUNTER32);
 	break;
     case MESH_PTBL_KEEPAL_S:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.n_keepalives_sent;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.n_keepalives_sent,
+	    SMI_COUNTER32);
 	break;
     case MESH_PTBL_KEEPAL_R:
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-	Answer->type = SMI_COUNTER32;
-	*(Answer->val.integer) = p->stats.n_keepalives_recv;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    p->stats.n_keepalives_recv,
+	    SMI_COUNTER32);
 	break;
-
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
@@ -273,67 +239,77 @@
 variable_list *
 snmp_prfSysFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     static struct rusage rusage;
-
     debug(49, 5) ("snmp_prfSysFn: Processing request with magic %d!\n", Var->name[LEN_SQ_PRF + 1]);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-    Answer->val_len = sizeof(snint);
-    Answer->val.integer = xmalloc(Answer->val_len);
-    Answer->type = ASN_INTEGER;
-
     switch (Var->name[LEN_SQ_PRF + 1]) {
     case PERF_SYS_PF:
 	squid_getrusage(&rusage);
-	*(Answer->val.integer) = rusage_pagefaults(&rusage);
-	Answer->type = SMI_COUNTER32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    rusage_pagefaults(&rusage),
+	    SMI_COUNTER32);
 	break;
     case PERF_SYS_NUMR:
-	*(Answer->val.integer) = IOStats.Http.reads;
-	Answer->type = SMI_COUNTER32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    IOStats.Http.reads,
+	    SMI_COUNTER32);
 	break;
     case PERF_SYS_MEMUSAGE:
-	*(Answer->val.integer) = (snint) memTotalAllocated() >> 10;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) memTotalAllocated() >> 10,
+	    ASN_INTEGER);
 	break;
     case PERF_SYS_CPUTIME:
 	squid_getrusage(&rusage);
-	*(Answer->val.integer) = (snint) rusage_cputime(&rusage);
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) rusage_cputime(&rusage),
+	    ASN_INTEGER);
 	break;
     case PERF_SYS_CPUUSAGE:
 	squid_getrusage(&rusage);
-	*(Answer->val.integer) = (snint)
-	    dpercent(rusage_cputime(&rusage), tvSubDsec(squid_start, current_time));
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) dpercent(rusage_cputime(&rusage), tvSubDsec(squid_start, current_time)),
+	    ASN_INTEGER);
 	break;
     case PERF_SYS_MAXRESSZ:
 	squid_getrusage(&rusage);
-	*(Answer->val.integer) = (snint) rusage_maxrss(&rusage);
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) rusage_maxrss(&rusage),
+	    ASN_INTEGER);
 	break;
     case PERF_SYS_CURLRUEXP:
-	Answer->type = SMI_TIMETICKS;
-	*(Answer->val.integer) = (snint) (storeExpiredReferenceAge() * 100);
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+#if !HEAP_REPLACEMENT
+	    (snint) (storeExpiredReferenceAge() * 100),
+#else
+	    0,
+#endif
+	    SMI_TIMETICKS);
 	break;
     case PERF_SYS_CURUNLREQ:
-	*(Answer->val.integer) = (snint) Counter.unlink.requests;
-	Answer->type = SMI_COUNTER32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) Counter.unlink.requests,
+	    SMI_COUNTER32);
 	break;
     case PERF_SYS_CURUNUSED_FD:
-	*(Answer->val.integer) = (snint) Squid_MaxFD - Number_FD;
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) Squid_MaxFD - Number_FD,
+	    SMI_GAUGE32);
 	break;
     case PERF_SYS_CURRESERVED_FD:
-	*(Answer->val.integer) = (snint) Number_FD;
-	Answer->type = SMI_GAUGE32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) Number_FD,
+	    SMI_GAUGE32);
 	break;
     case PERF_SYS_NUMOBJCNT:
-	*(Answer->val.integer) = (snint) memInUse(MEM_STOREENTRY);
-	Answer->type = SMI_COUNTER32;
+	Answer = snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) memInUse(MEM_STOREENTRY),
+	    SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
-	snmp_var_free(Answer);
-	return (NULL);
+	break;
     }
     return Answer;
 }
@@ -341,94 +317,107 @@
 variable_list *
 snmp_prfProtoFn(variable_list * Var, snint * ErrP)
 {
-    variable_list *Answer;
+    variable_list *Answer = NULL;
     static StatCounters *f = NULL;
     static StatCounters *l = NULL;
     double x;
     int minutes;
-
     debug(49, 5) ("snmp_prfProtoFn: Processing request with magic %d!\n", Var->name[LEN_SQ_PRF]);
-
-    Answer = snmp_var_new(Var->name, Var->name_length);
     *ErrP = SNMP_ERR_NOERROR;
-
     switch (Var->name[LEN_SQ_PRF + 1]) {
     case PERF_PROTOSTAT_AGGR:	/* cacheProtoAggregateStats */
-	Answer->type = SMI_COUNTER32;
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
 	switch (Var->name[LEN_SQ_PRF + 2]) {
 	case PERF_PROTOSTAT_AGGR_HTTP_REQ:
-	    *(Answer->val.integer) = (snint) Counter.client_http.requests;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.requests,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_HTTP_HITS:
-	    *(Answer->val.integer) = (snint) Counter.client_http.hits;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.hits,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_HTTP_ERRORS:
-	    *(Answer->val.integer) = (snint) Counter.client_http.errors;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.errors,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN:
-	    *(Answer->val.integer) = (snint) Counter.client_http.kbytes_in.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.kbytes_in.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT:
-	    *(Answer->val.integer) = (snint) Counter.client_http.kbytes_out.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.kbytes_out.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_ICP_S:
-	    *(Answer->val.integer) = (snint) Counter.icp.pkts_sent;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.icp.pkts_sent,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_ICP_R:
-	    *(Answer->val.integer) = (snint) Counter.icp.pkts_recv;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.icp.pkts_recv,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_ICP_SKB:
-	    *(Answer->val.integer) = (snint) Counter.icp.kbytes_sent.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.icp.kbytes_sent.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_ICP_RKB:
-	    *(Answer->val.integer) = (snint) Counter.icp.kbytes_recv.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.icp.kbytes_recv.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_REQ:
-	    *(Answer->val.integer) = (snint) Counter.server.all.requests;
-	    Answer->type = SMI_INTEGER;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.server.all.requests,
+		SMI_INTEGER);
 	    break;
 	case PERF_PROTOSTAT_AGGR_ERRORS:
-	    *(Answer->val.integer) = (snint) Counter.server.all.errors;
-	    Answer->type = SMI_INTEGER;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.server.all.errors,
+		SMI_INTEGER);
 	    break;
 	case PERF_PROTOSTAT_AGGR_KBYTES_IN:
-	    *(Answer->val.integer) = (snint) Counter.server.all.kbytes_in.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.server.all.kbytes_in.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_KBYTES_OUT:
-	    *(Answer->val.integer) = (snint) Counter.server.all.kbytes_out.kb;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.server.all.kbytes_out.kb,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_CURSWAP:
-	    *(Answer->val.integer) = (snint) store_swap_size;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) store_swap_size,
+		SMI_COUNTER32);
 	    break;
 	case PERF_PROTOSTAT_AGGR_CLIENTS:
-	    *(Answer->val.integer) = (snint) Counter.client_http.clients;
+	    Answer = snmp_var_new_integer(Var->name, Var->name_length,
+		(snint) Counter.client_http.clients,
+		SMI_COUNTER32);
 	    break;
 	default:
 	    *ErrP = SNMP_ERR_NOSUCHNAME;
-	    snmp_var_free(Answer);
-	    return (NULL);
+	    break;
 	}
 	return Answer;
     case PERF_PROTOSTAT_MEDIAN:
-
 	if (Var->name_length == LEN_SQ_PRF + 5)
 	    minutes = Var->name[LEN_SQ_PRF + 4];
 	else
 	    break;
 	if ((minutes < 1) || (minutes > 60))
 	    break;
-
 	f = snmpStatGet(0);
 	l = snmpStatGet(minutes);
-
 	debug(49, 8) ("median: min= %d, %d l= %x , f = %x\n", minutes,
 	    Var->name[LEN_SQ_PRF + 3], l, f);
-	Answer->type = SMI_INTEGER;
-	Answer->val_len = sizeof(snint);
-	Answer->val.integer = xmalloc(Answer->val_len);
-
 	debug(49, 8) ("median: l= %x , f = %x\n", l, f);
 	switch (Var->name[LEN_SQ_PRF + 3]) {
 	case PERF_MEDIAN_TIME:
@@ -467,13 +456,12 @@
 	    break;
 	default:
 	    *ErrP = SNMP_ERR_NOSUCHNAME;
-	    snmp_var_free(Answer);
-	    return (NULL);
+	    return NULL;
 	}
-	*(Answer->val.integer) = (snint) x;
-	return Answer;
+	return snmp_var_new_integer(Var->name, Var->name_length,
+	    (snint) x,
+	    SMI_INTEGER);
     }
     *ErrP = SNMP_ERR_NOSUCHNAME;
-    snmp_var_free(Answer);
-    return (NULL);
+    return NULL;
 }
Index: squid/src/snmp_core.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/snmp_core.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/snmp_core.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/snmp_core.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: snmp_core.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: snmp_core.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 49    SNMP support
  * AUTHOR: Glenn Chisholm
@@ -483,7 +483,7 @@
 /*
  * Turn SNMP packet into a PDU, check available ACL's
  */
-void
+static void
 snmpDecodePacket(snmp_request_t * rq)
 {
     struct snmp_pdu *PDU;
@@ -519,7 +519,7 @@
 /*
  * Packet OK, ACL Check OK, Create reponse.
  */
-void
+static void
 snmpConstructReponse(snmp_request_t * rq)
 {
     struct snmp_session Session;
@@ -546,7 +546,7 @@
  * 
  * If configured forward any reponses which are not for this agent.
  */
-struct snmp_pdu *
+static struct snmp_pdu *
 snmpAgentResponse(struct snmp_pdu *PDU)
 {
     struct snmp_pdu *Answer = NULL;
@@ -632,7 +632,7 @@
     return (Answer);
 }
 
-oid_ParseFn *
+static oid_ParseFn *
 snmpTreeGet(oid * Current, snint CurrentLen)
 {
     oid_ParseFn *Fn = NULL;
@@ -659,7 +659,7 @@
     return (Fn);
 }
 
-oid_ParseFn *
+static oid_ParseFn *
 snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
 {
     oid_ParseFn *Fn = NULL;
@@ -725,7 +725,7 @@
     return (Fn);
 }
 
-oid *
+static oid *
 static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
@@ -740,7 +740,7 @@
     return (instance);
 }
 
-oid *
+static oid *
 time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
@@ -767,7 +767,7 @@
     return (instance);
 }
 
-oid *
+static oid *
 peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
@@ -826,7 +826,7 @@
     return (instance);
 }
 
-oid *
+static oid *
 client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
@@ -874,7 +874,7 @@
 /* 
  * Returns a the sibling object in the tree
  */
-mib_tree_entry *
+static mib_tree_entry *
 snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
 {
     mib_tree_entry *next = NULL;
@@ -897,7 +897,7 @@
 /* 
  * Returns the requested child object or NULL if it does not exist
  */
-mib_tree_entry *
+static mib_tree_entry *
 snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
 {
     mib_tree_entry *next = NULL;
@@ -915,7 +915,7 @@
 /*
  * Adds a node to the MIB tree structure and adds the appropriate children
  */
-mib_tree_entry *
+static mib_tree_entry *
 #if STDC_HEADERS
 snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
 #else
@@ -968,7 +968,7 @@
 /* 
  * Returns the list of parameters in an oid
  */
-oid *
+static oid *
 #if STDC_HEADERS
 snmpCreateOid(int length,...)
 #else
@@ -1002,7 +1002,7 @@
 /*
  * Allocate space for, and copy, an OID.  Returns new oid.
  */
-oid *
+static oid *
 snmpOidDup(oid * A, snint ALen)
 {
     oid *Ans = xmalloc(sizeof(oid) * ALen);
Index: squid/src/squid.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/squid.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/squid.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/squid.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: squid.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -51,10 +51,12 @@
 #define CHANGE_FD_SETSIZE 0
 #endif
 
-/* Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2)
- * to return EINVAL. */
-/* Marian Durkovic <marian@svf.stuba.sk> */
-/* Peter Wemm <peter@spinner.DIALix.COM> */
+/*
+ * Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2)
+ * to return EINVAL.
+ * --Marian Durkovic <marian@svf.stuba.sk>
+ * --Peter Wemm <peter@spinner.DIALix.COM>
+ */
 #if defined(_SQUID_FREEBSD_)
 #include <osreldate.h>
 #if __FreeBSD_version < 220000
@@ -63,6 +65,15 @@
 #endif
 #endif
 
+/*
+ * Trying to redefine CHANGE_FD_SETSIZE causes a slew of warnings
+ * on Mac OS X Server.
+ */
+#if defined(_SQUID_APPLE_)
+#undef CHANGE_FD_SETSIZE
+#define CHANGE_FD_SETSIZE 0
+#endif
+
 /* Increase FD_SETSIZE if SQUID_MAXFD is bigger */
 #if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE
 #define FD_SETSIZE SQUID_MAXFD
@@ -175,6 +186,9 @@
 #if HAVE_GETOPT_H
 #include <getopt.h>
 #endif
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
 
 #if HAVE_DIRENT_H
 #include <dirent.h>
@@ -222,6 +236,7 @@
 #ifdef HAVE_SYSLOG_H
 #ifdef _SQUID_AIX_
 #define _XOPEN_EXTENDED_SOURCE
+#define _XOPEN_SOURCE_EXTENDED 1
 #endif
 #include <syslog.h>
 #endif
@@ -344,6 +359,10 @@
 #endif
 
 #include "hash.h"
+#include "rfc1035.h"
+#if HEAP_REPLACEMENT
+#include "heap.h"
+#endif
 
 #include "defines.h"
 #include "enums.h"
@@ -353,7 +372,14 @@
 #include "globals.h"
 
 #include "util.h"
+
+/*
+ * Mac OS X Server already has radix.h as a standard header, so
+ * this causes conflicts.
+ */
+#ifndef _SQUID_APPLE_
 #include "radix.h"
+#endif
 
 #if !HAVE_TEMPNAM
 #include "tempnam.h"
@@ -385,9 +411,17 @@
 #define strdup +
 #endif
 
-#if SQUID_SNMP
-extern struct snmp_mib_tree *Mib;
+/*
+ * Hey dummy, don't be tempted to move this to lib/config.h.in again.  O_NONBLOCK
+ * will not be defined there because you didn't #include <fcntl.h> yet.
+ */
+#if defined(O_NONBLOCK) && !defined(_SQUID_SUNOS_) && !defined(_SQUID_SOLARIS_)
+#define SQUID_NONBLOCK O_NONBLOCK
+#else
+#define SQUID_NONBLOCK O_NDELAY
 #endif
 
+#define SWAP_DIR_SHIFT 24
+#define SWAP_FILE_MASK 0x00FFFFFF
 
 #endif /* SQUID_H */
Index: squid/src/ssl.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/ssl.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/ssl.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ssl.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: ssl.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -119,7 +119,12 @@
 sslDeferServerRead(int fdnotused, void *data)
 {
     SslStateData *s = data;
-    return delayBytesWanted(s->delay_id, 0, 1) == 0;
+    int i = delayBytesWanted(s->delay_id, 0, INT_MAX);
+    if (i == INT_MAX)
+	return 0;
+    if (i == 0)
+	return 1;
+    return -1;
 }
 #endif
 
@@ -155,7 +160,8 @@
 		0);
 	}
 #if DELAY_POOLS
-	/* If this was allowed to return 0, there would be a possibility
+	/*
+	 * If this was allowed to return 0, there would be a possibility
 	 * of the socket becoming "hung" with data accumulating but no
 	 * write handler (server.len==0) and no read handler (!(0<0)) and
 	 * no data flowing in the other direction.  Hence the argument of
@@ -206,8 +212,8 @@
     }
     cbdataLock(sslState);
     if (len < 0) {
-	debug(50, 1) ("sslReadServer: FD %d: read failure: %s\n",
-	    fd, xstrerror());
+	debug(50, ignoreErrno(errno) ? 3 : 1)
+	    ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror());
 	if (!ignoreErrno(errno))
 	    comm_close(fd);
     } else if (len == 0) {
@@ -240,7 +246,7 @@
     }
     cbdataLock(sslState);
     if (len < 0) {
-	debug(50, 1) ("sslReadClient: FD %d: read failure: %s\n",
+	debug(50, ECONNRESET == errno ? 3 : 1) ("sslReadClient: FD %d: read failure: %s\n",
 	    fd, xstrerror());
 	if (!ignoreErrno(errno))
 	    comm_close(fd);
@@ -281,8 +287,8 @@
     }
     cbdataLock(sslState);
     if (len < 0) {
-	debug(50, 1) ("sslWriteServer: FD %d: write failure: %s.\n",
-	    fd, xstrerror());
+	debug(50, ignoreErrno(errno) ? 3 : 1)
+	    ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror());
 	if (!ignoreErrno(errno))
 	    comm_close(fd);
     }
@@ -322,8 +328,8 @@
     }
     cbdataLock(sslState);
     if (len < 0) {
-	debug(50, 1) ("sslWriteClient: FD %d: write failure: %s.\n",
-	    fd, xstrerror());
+	debug(50, ignoreErrno(errno) ? 3 : 1)
+	    ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror());
 	if (!ignoreErrno(errno))
 	    comm_close(fd);
     }
@@ -527,6 +533,12 @@
     } else {
 	sslState->port = CACHE_HTTP_PORT;
     }
+    if (fs->peer) {
+	sslState->request->peer_login = fs->peer->login;
+	sslState->request->flags.proxying = 1;
+    } else {
+	sslState->request->flags.proxying = 0;
+    }
 #if DELAY_POOLS
     /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
     if (g && g->options.no_delay && sslState->delay_id) {
Index: squid/src/stat.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/stat.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/stat.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/stat.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: stat.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: stat.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -79,7 +79,7 @@
 static OBJH statClientRequests;
 
 #ifdef XMALLOC_STATISTICS
-static void info_get_mallstat(int, int, StoreEntry *);
+static void info_get_mallstat(int, int, void *);
 #endif
 
 StatCounters CountHist[N_COUNT_HIST];
@@ -269,10 +269,11 @@
     if (mem != NULL) {
 	storeAppendPrintf(s, "\tinmem_lo: %d\n", (int) mem->inmem_lo);
 	storeAppendPrintf(s, "\tinmem_hi: %d\n", (int) mem->inmem_hi);
-	storeAppendPrintf(s, "\tswapout: %d bytes done, %d queued, FD %d\n",
-	    (int) mem->swapout.done_offset,
-	    (int) mem->swapout.queue_offset,
-	    mem->swapout.fd);
+	storeAppendPrintf(s, "\tswapout: %d bytes queued\n",
+	    (int) mem->swapout.queue_offset);
+	if (mem->swapout.sio)
+	    storeAppendPrintf(s, "\tswapout: %d bytes written\n",
+		(int) storeOffset(mem->swapout.sio));
 	for (i = 0, sc = &mem->clients[i]; sc != NULL; sc = sc->next, i++) {
 	    if (sc->callback_data == NULL)
 		continue;
@@ -283,8 +284,6 @@
 		(int) sc->seen_offset);
 	    storeAppendPrintf(s, "\t\tcopy_size: %d\n",
 		(int) sc->copy_size);
-	    storeAppendPrintf(s, "\t\tswapin_fd: %d\n",
-		(int) sc->swapin_fd);
 	    storeAppendPrintf(s, "\t\tflags:");
 	    if (sc->flags.disk_io_pending)
 		storeAppendPrintf(s, " disk_io_pending");
@@ -369,8 +368,8 @@
 {
     if (e->mem_obj == NULL)
 	return 0;
-    if (e->mem_obj->swapout.fd < 0)
-	return 0;;
+    if (e->mem_obj->swapout.sio == NULL)
+	return 0;
     return 1;
 }
 
@@ -384,8 +383,9 @@
 
 #ifdef XMALLOC_STATISTICS
 static void
-info_get_mallstat(int size, int number, StoreEntry * sentry)
+info_get_mallstat(int size, int number, void *data)
 {
+    StoreEntry *sentry = data;
     if (number > 0)
 	storeAppendPrintf(sentry, "\t%d = %d\n", size, number);
 }
@@ -489,8 +489,13 @@
 	store_swap_size);
     storeAppendPrintf(sentry, "\tStorage Mem size:\t%d KB\n",
 	(int) (store_mem_size >> 10));
+#if HEAP_REPLACEMENT
+    storeAppendPrintf(sentry, "\tStorage Replacement Threshold:\t%f\n",
+	heap_peepminkey(store_heap));
+#else
     storeAppendPrintf(sentry, "\tStorage LRU Expiration Age:\t%6.2f days\n",
 	(double) storeExpiredReferenceAge() / 86400.0);
+#endif
     storeAppendPrintf(sentry, "\tMean Object Size:\t%0.2f KB\n",
 	n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0);
     storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%d\n",
@@ -936,6 +941,7 @@
      */
     statHistEnumInit(&C->cd.on_xition_count, CacheDigestHashFuncCount);
     statHistEnumInit(&C->comm_icp_incoming, INCOMING_ICP_MAX);
+    statHistEnumInit(&C->comm_dns_incoming, INCOMING_DNS_MAX);
     statHistEnumInit(&C->comm_http_incoming, INCOMING_HTTP_MAX);
     statHistIntInit(&C->select_fds_hist, SQUID_MAXFD);
 }
@@ -1332,6 +1338,7 @@
 		conn->defer.n, conn->defer.until);
 	}
 	storeAppendPrintf(s, "uri %s\n", http->uri);
+	storeAppendPrintf(s, "log_type %s\n", log_tags[http->log_type]);
 	storeAppendPrintf(s, "out.offset %d, out.size %d\n",
 	    http->out.offset, http->out.size);
 	storeAppendPrintf(s, "req_sz %d\n", http->req_sz);
Index: squid/src/store.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
@@ -21,12 +21,12 @@
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
@@ -61,7 +61,6 @@
 const char *swapStatusStr[] =
 {
     "SWAPOUT_NONE",
-    "SWAPOUT_OPENING",
     "SWAPOUT_WRITING",
     "SWAPOUT_DONE"
 };
@@ -88,16 +87,26 @@
 static int storeKeepInMemory(const StoreEntry *);
 static OBJH storeCheckCachableStats;
 static EVH storeLateRelease;
+#if HEAP_REPLACEMENT
+static heap_key_func HeapKeyGen_StoreEntry_LFUDA;
+static heap_key_func HeapKeyGen_StoreEntry_GDSF;
+static heap_key_func HeapKeyGen_StoreEntry_LRU;
+#endif
 
 /*
  * local variables
  */
+#if HEAP_REPLACEMENT
+/*
+ * The heap equivalent of inmem_list, inmem_heap, is in globals.c so other
+ * modules can access it when updating object metadata (e.g., refcount)
+ */
+#else
 static dlink_list inmem_list;
+#endif
 static int store_pages_max = 0;
 static int store_swap_high = 0;
 static int store_swap_low = 0;
-static int store_swap_mid = 0;
-static int store_maintain_rate;
 static Stack LateReleaseStack;
 
 static MemObject *
@@ -107,7 +116,6 @@
     mem->reply = httpReplyCreate();
     mem->url = xstrdup(url);
     mem->log_url = xstrdup(log_url);
-    mem->swapout.fd = -1;
     mem->object_sz = -1;
     mem->fd = -1;
     /* XXX account log_url */
@@ -135,14 +143,9 @@
     debug(20, 3) ("destroy_MemObject: destroying %p\n", mem);
     e->mem_obj = NULL;
     if (!shutting_down)
-	assert(mem->swapout.fd == -1);
+	assert(mem->swapout.sio == NULL);
     stmemFree(&mem->data_hdr);
     mem->inmem_hi = 0;
-    /* XXX account log_url */
-#if USE_ASYNC_IO
-    while (mem->clients != NULL)
-	storeUnregister(e, mem->clients->callback_data);
-#endif
     /*
      * There is no way to abort FD-less clients, so they might
      * still have mem->clients set if mem->fd == -1
@@ -153,7 +156,7 @@
     mem->request = NULL;
     ctx_exit(ctx);		/* must exit before we free mem->url */
     safe_free(mem->url);
-    safe_free(mem->log_url);
+    safe_free(mem->log_url);	/* XXX account log_url */
     memFree(mem, MEM_MEMOBJECT);
 }
 
@@ -179,14 +182,31 @@
 	e, storeKeyText(key));
     e->key = storeKeyDup(key);
     hash_join(store_table, (hash_link *) e);
+#if HEAP_REPLACEMENT
+    if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
+	(void) 0;
+    } else {
+	e->node = heap_insert(store_heap, e);
+	debug(20, 4) ("storeHashInsert: inserted node %p\n", e->node);
+    }
+#else
     dlinkAdd(e, &e->lru, &store_list);
+#endif
 }
 
 static void
 storeHashDelete(StoreEntry * e)
 {
     hash_remove_link(store_table, (hash_link *) e);
+#if HEAP_REPLACEMENT
+    if (e->node) {
+	debug(20, 4) ("storeHashDelete: deleting node %p\n", e->node);
+	heap_delete(store_heap, e->node);
+	e->node = NULL;
+    }
+#else
     dlinkDelete(&e->lru, &store_list);
+#endif
     storeKeyFree(e->key);
     e->key = NULL;
 }
@@ -213,8 +233,19 @@
 storeLockObject(StoreEntry * e)
 {
     if (e->lock_count++ == 0) {
+#if HEAP_REPLACEMENT
+	/*
+	 * There is no reason to take any action here.  Squid by
+	 * default is moving locked objects to the end of the LRU
+	 * list to keep them from getting bumped into by the
+	 * replacement algorithm.  We can't do that so we will just
+	 * have to handle them.
+	 */
+	debug(20, 4) ("storeLockObject: just locked node %p\n", e->node);
+#else
 	dlinkDelete(&e->lru, &store_list);
 	dlinkAdd(e, &e->lru, &store_list);
+#endif
     }
     debug(20, 3) ("storeLockObject: key '%s' count=%d\n",
 	storeKeyText(e->key), (int) e->lock_count);
@@ -250,6 +281,9 @@
     if (e->store_status == STORE_PENDING)
 	EBIT_SET(e->flags, RELEASE_REQUEST);
     assert(storePendingNClients(e) == 0);
+#if HEAP_REPLACEMENT
+    storeHeapPositionUpdate(e);
+#endif
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
 	storeRelease(e);
     else if (storeKeepInMemory(e)) {
@@ -259,14 +293,23 @@
     } else {
 	storePurgeMem(e);
 	if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
+#if HEAP_REPLACEMENT
+	    /*
+	     * Squid/LRU is moving things around in the linked list in order
+	     * to keep from bumping into them when purging from the LRU list.
+	     */
+	    debug(20, 4) ("storeUnlockObject: purged private node %p\n",
+		e->node);
+#else
 	    dlinkDelete(&e->lru, &store_list);
 	    dlinkAddTail(e, &e->lru, &store_list);
+#endif
 	}
     }
     return 0;
 }
 
-/* Lookup an object in the cache. 
+/* Lookup an object in the cache.
  * return just a reference to object, don't start swapping in yet. */
 StoreEntry *
 storeGet(const cache_key * key)
@@ -332,6 +375,11 @@
      * If RELEASE_REQUEST is set, then ENTRY_CACHABLE should not
      * be set, and storeSetPublicKey() should not be called.
      */
+#if HEAP_REPLACEMENT
+    if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+	debug(20, 1) ("assertion failed: RELEASE key %s, url %s\n",
+	    e->key, mem->url);
+#endif
     assert(!EBIT_TEST(e->flags, RELEASE_REQUEST));
     newkey = storeKeyPublic(mem->url, mem->method);
     if ((e2 = (StoreEntry *) hash_lookup(store_table, newkey))) {
@@ -408,14 +456,8 @@
     }
     if (EBIT_TEST(e->flags, DELAY_SENDING))
 	return;
-#ifdef OPTIMISTIC_IO
-    storeLockObject(e);
-#endif
     InvokeHandlers(e);
-    storeCheckSwapOut(e);
-#ifdef OPTIMISTIC_IO
-    storeUnlockObject(e);
-#endif
+    storeSwapOut(e);
 }
 
 void
@@ -504,6 +546,9 @@
     } else if (e->mem_obj->inmem_hi > Config.Store.maxObjectSize) {
 	debug(20, 2) ("storeCheckCachable: NO: too big\n");
 	store_check_cachable_hist.no.too_big++;
+    } else if (e->mem_obj->reply->content_length > (int) Config.Store.maxObjectSize) {
+	debug(20, 2) ("storeCheckCachable: NO: too big\n");
+	store_check_cachable_hist.no.too_big++;
     } else if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
 	debug(20, 3) ("storeCheckCachable: NO: private key\n");
 	store_check_cachable_hist.no.private_key++;
@@ -520,10 +565,18 @@
     } else if (fdNFree() < RESERVED_FD) {
 	debug(20, 2) ("storeCheckCachable: NO: too many FD's open\n");
 	store_check_cachable_hist.no.too_many_open_fds++;
+#if HEAP_REPLACEMENT
+	/*
+	 * With the HEAP-based replacement policies a low reference
+	 * age should not prevent cacheability of an object.  We
+	 * do not use LRU age at all.
+	 */
+#else
     } else if (storeExpiredReferenceAge() < 300) {
 	debug(20, 2) ("storeCheckCachable: NO: LRU Age = %d\n",
 	    storeExpiredReferenceAge());
 	store_check_cachable_hist.no.lru_age_too_low++;
+#endif
     } else {
 	store_check_cachable_hist.yes.Default++;
 	return 1;
@@ -588,13 +641,13 @@
 	e->mem_obj->request->hier.store_complete_stop = current_time;
 #endif
     InvokeHandlers(e);
-    storeCheckSwapOut(e);
+    storeSwapOut(e);
 }
 
 /*
  * Someone wants to abort this transfer.  Set the reason in the
  * request structure, call the server-side callback and mark the
- * entry for releasing 
+ * entry for releasing
  */
 void
 storeAbort(StoreEntry * e)
@@ -608,8 +661,6 @@
     storeReleaseRequest(e);
     EBIT_SET(e->flags, ENTRY_ABORTED);
     storeSetMemStatus(e, NOT_IN_MEMORY);
-    /* No DISK swap for negative cached object */
-    e->swap_status = SWAPOUT_NONE;
     e->store_status = STORE_OK;
     /*
      * We assign an object length here.  The only other place we assign
@@ -630,19 +681,8 @@
     InvokeHandlers(e);
     /* Do we need to close the swapout file? */
     /* Not if we never started swapping out */
-    /* But we may need to cancel an open/stat in progress if using ASYNC */
-#if USE_ASYNC_IO
-    aioCancel(-1, e);
-#endif
     if (e->swap_file_number > -1) {
-#if USE_ASYNC_IO
-	/* Need to cancel any pending ASYNC writes right now */
-	if (mem->swapout.fd >= 0)
-	    aioCancel(mem->swapout.fd, NULL);
-#endif
-	/* we have to close the disk file if there is no write pending */
-	if (!storeSwapOutWriteQueued(mem))
-	    storeSwapOutFileClose(e);
+	storeSwapOutFileClose(e);
     }
     storeUnlockObject(e);	/* unlock */
 }
@@ -655,18 +695,56 @@
     int released = 0;
     static time_t last_check = 0;
     int pages_needed;
-    dlink_node *m;
+    int locked = 0;
+#if !HEAP_REPLACEMENT
     dlink_node *head;
+    dlink_node *m;
     dlink_node *prev = NULL;
+#else
+    heap_key age;
+    heap_key min_age = 0.0;
+    link_list *locked_entries = NULL;
+#endif
     if (squid_curtime == last_check)
 	return;
     last_check = squid_curtime;
     pages_needed = (size / SM_PAGE_SIZE) + 1;
     if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
 	return;
-    if (store_rebuilding)
+    if (store_dirs_rebuilding)
 	return;
     debug(20, 2) ("storeGetMemSpace: Starting, need %d pages\n", pages_needed);
+#if HEAP_REPLACEMENT
+    while (heap_nodes(inmem_heap) > 0) {
+	age = heap_peepminkey(inmem_heap);
+	e = heap_extractmin(inmem_heap);
+	e->mem_obj->node = NULL;	/* no longer in the heap */
+	if (storeEntryLocked(e)) {
+	    locked++;
+	    debug(20, 5) ("storeGetMemSpace: locked key %s\n",
+		storeKeyText(e->key));
+	    linklistPush(&locked_entries, e);
+	    continue;
+	}
+	released++;
+	debug(20, 3) ("Released memory object with key %f size %d refs %d url %s\n",
+	    age, e->swap_file_sz, e->refcount, e->mem_obj->url);
+	min_age = age;
+	storePurgeMem(e);
+	if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
+	    break;
+    }
+    /*
+     * Increase the heap age factor.
+     */
+    if (min_age > 0)
+	inmem_heap->age = min_age;
+    /*
+     * Reinsert all bumped locked entries back into heap...
+     */
+    while ((e = linklistShift(&locked_entries)))
+	e->mem_obj->node = heap_insert(inmem_heap, e);
+#else
     head = inmem_list.head;
     for (m = inmem_list.tail; m; m = prev) {
 	if (m == head)
@@ -674,6 +752,7 @@
 	prev = m->prev;
 	e = m->data;
 	if (storeEntryLocked(e)) {
+	    locked++;
 	    dlinkDelete(m, &inmem_list);
 	    dlinkAdd(e, m, &inmem_list);
 	    continue;
@@ -683,6 +762,9 @@
 	if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
 	    break;
     }
+#endif
+    debug(20, 3) ("storeGetMemSpace: released %d/%d locked %d\n",
+	released, hot_obj_count, locked);
     debug(20, 3) ("storeGetMemSpace stats:\n");
     debug(20, 3) ("  %6d HOT objects\n", hot_obj_count);
     debug(20, 3) ("  %6d were released\n", released);
@@ -692,7 +774,7 @@
 #define MAINTAIN_MAX_SCAN	1024
 #define MAINTAIN_MAX_REMOVE	64
 
-/* 
+/*
  * This routine is to be called by main loop in main.c.
  * It removes expired objects on only one bucket for each time called.
  * returns the number of objects removed
@@ -702,8 +784,6 @@
 void
 storeMaintainSwapSpace(void *datanotused)
 {
-    dlink_node *m;
-    dlink_node *prev = NULL;
     StoreEntry *e = NULL;
     int scanned = 0;
     int locked = 0;
@@ -712,8 +792,21 @@
     int max_remove;
     double f;
     static time_t last_warn_time = 0;
+#if !HEAP_REPLACEMENT
+    dlink_node *m;
+    dlink_node *prev = NULL;
+#else
+    heap_key age;
+    heap_key min_age = 0.0;
+    link_list *locked_entries = NULL;
+#if HEAP_REPLACEMENT_DEBUG
+    if (!verify_heap_property(store_heap)) {
+	debug(20, 1) ("Heap property violated!\n");
+    }
+#endif
+#endif
     /* We can't delete objects while rebuilding swap */
-    if (store_rebuilding) {
+    if (store_dirs_rebuilding) {
 	eventAdd("MaintainSwapSpace", storeMaintainSwapSpace, NULL, 1.0, 1);
 	return;
     } else {
@@ -725,6 +818,72 @@
     }
     debug(20, 3) ("storeMaintainSwapSpace: f=%f, max_scan=%d, max_remove=%d\n",
 	f, max_scan, max_remove);
+#if HEAP_REPLACEMENT
+    while (heap_nodes(store_heap) > 0) {
+	if (store_swap_size < store_swap_low)
+	    break;
+	if (expired >= max_remove)
+	    break;
+	if (scanned >= max_scan)
+	    break;
+	age = heap_peepminkey(store_heap);
+	e = heap_extractmin(store_heap);
+	e->node = NULL;		/* no longer in the heap */
+	scanned++;
+	if (storeEntryLocked(e)) {
+	    /*
+	     * Entry is in use ... put it in a linked list to ignore it.
+	     */
+	    if (!EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
+		/*
+		 * If this was a "SPECIAL" do not add it back into the heap.
+		 * It will always be "SPECIAL" and therefore never removed.
+		 */
+		debug(20, 4) ("storeMaintainSwapSpace: locked url %s\n",
+		    (e->mem_obj && e->mem_obj->url) ? e->mem_obj->url : storeKeyText(e->key));
+		linklistPush(&locked_entries, e);
+	    }
+	    locked++;
+	    continue;
+	} else if (storeCheckExpired(e)) {
+	    /*
+	     * Note: This will not check the reference age ifdef
+	     * HEAP_REPLACEMENT, but it does some other useful
+	     * checks...
+	     */
+	    expired++;
+	    debug(20, 3) ("Released store object age %f size %d refs %d key %s\n",
+		age, e->swap_file_sz, e->refcount, storeKeyText(e->key));
+	    min_age = age;
+	    storeRelease(e);
+	} else {
+	    /*
+	     * Did not expire the object so we need to add it back
+	     * into the heap!
+	     */
+	    debug(20, 5) ("storeMaintainSwapSpace: non-expired %s\n",
+		storeKeyText(e->key));
+	    linklistPush(&locked_entries, e);
+	    continue;
+	}
+	if (store_swap_size < store_swap_low)
+	    break;
+	else if (expired >= max_remove)
+	    break;
+	else if (scanned >= max_scan)
+	    break;
+    }
+    /*
+     * Bump the heap age factor.
+     */
+    if (min_age > 0.0)
+	store_heap->age = min_age;
+    /*
+     * Reinsert all bumped locked entries back into heap...
+     */
+    while ((e = linklistShift(&locked_entries)))
+	e->node = heap_insert(store_heap, e);
+#else
     for (m = store_list.tail; m; m = prev) {
 	prev = m->prev;
 	e = m->data;
@@ -751,6 +910,9 @@
 	if (scanned >= max_scan)
 	    break;
     }
+#endif
+    debug(20, (expired ? 2 : 3)) ("storeMaintainSwapSpace: scanned %d/%d removed %d/%d locked %d f=%.03f\n",
+	scanned, max_scan, expired, max_remove, locked, f);
     debug(20, 3) ("storeMaintainSwapSpace stats:\n");
     debug(20, 3) ("  %6d objects\n", memInUse(MEM_STOREENTRY));
     debug(20, 3) ("  %6d were scanned\n", scanned);
@@ -780,13 +942,7 @@
 	storeReleaseRequest(e);
 	return;
     }
-#if USE_ASYNC_IO
-    /*
-     * Make sure all forgotten async ops are cancelled
-     */
-    aioCancel(-1, e);
-#endif
-    if (store_rebuilding) {
+    if (store_dirs_rebuilding && e->swap_file_number > -1) {
 	storeSetPrivateKey(e);
 	if (e->mem_obj) {
 	    storeSetMemStatus(e, NOT_IN_MEMORY);
@@ -802,7 +958,7 @@
     }
     storeLog(STORE_LOG_RELEASE, e);
     if (e->swap_file_number > -1) {
-	storeUnlinkFileno(e->swap_file_number);
+	storeUnlink(e->swap_file_number);
 	storeDirMapBitReset(e->swap_file_number);
 	if (e->swap_status == SWAPOUT_DONE)
 	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
@@ -820,7 +976,7 @@
     StoreEntry *e;
     int i;
     static int n = 0;
-    if (store_rebuilding) {
+    if (store_dirs_rebuilding) {
 	eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
 	return;
     }
@@ -843,8 +999,6 @@
 {
     if (e->lock_count)
 	return 1;
-    if (e->swap_status == SWAPOUT_OPENING)
-	return 1;
     if (e->swap_status == SWAPOUT_WRITING)
 	return 1;
     if (e->store_status == STORE_PENDING)
@@ -914,16 +1068,15 @@
     /* ideally the full scan period should be configurable, for the
      * moment it remains at approximately 24 hours.  */
     store_hash_buckets = storeKeyHashBuckets(i);
-    store_maintain_rate = 86400 / store_hash_buckets;
-    assert(store_maintain_rate > 0);
-    debug(20, 1) ("Using %d Store buckets, replacement runs every %d second%s\n",
-	store_hash_buckets,
-	store_maintain_rate,
-	store_maintain_rate == 1 ? null_string : "s");
+    debug(20, 1) ("Using %d Store buckets\n", store_hash_buckets);
     debug(20, 1) ("Max Mem  size: %d KB\n", Config.memMaxSize >> 10);
     debug(20, 1) ("Max Swap size: %d KB\n", Config.Swap.maxSize);
 }
 
+#if HEAP_REPLACEMENT
+#include "store_heap_replacement.c"
+#endif
+
 void
 storeInit(void)
 {
@@ -933,19 +1086,42 @@
 	store_hash_buckets, storeKeyHashHash);
     storeDigestInit();
     storeLogOpen();
-    if (storeVerifyCacheDirs() < 0) {
-	xstrncpy(tmp_error_buf,
-	    "\tFailed to verify one of the swap directories, Check cache.log\n"
-	    "\tfor details.  Run 'squid -z' to create swap directories\n"
-	    "\tif needed, or if running Squid for the first time.",
-	    ERROR_BUF_SZ);
-	fatal(tmp_error_buf);
+#if HEAP_REPLACEMENT
+    /*
+     * Create new heaps with cache replacement policies attached to them.
+     * The cache replacement policy is specified as either GDSF or LFUDA in
+     * the squid.conf configuration file.  Note that the replacement policy
+     * applies only to the disk replacement algorithm.  Memory replacement
+     * always uses GDSF since we want to maximize object hit rate.
+     */
+    inmem_heap = new_heap(1000, HeapKeyGen_StoreEntry_GDSF);
+    if (Config.replPolicy) {
+	if (tolower(Config.replPolicy[0]) == 'g') {
+	    debug(20, 1) ("Using GDSF disk replacement policy\n");
+	    store_heap = new_heap(10000, HeapKeyGen_StoreEntry_GDSF);
+	} else if (tolower(Config.replPolicy[0]) == 'l') {
+	    if (tolower(Config.replPolicy[1]) == 'f') {
+		debug(20, 1) ("Using LFUDA disk replacement policy\n");
+		store_heap = new_heap(10000, HeapKeyGen_StoreEntry_LFUDA);
+	    } else if (tolower(Config.replPolicy[1]) == 'r') {
+		debug(20, 1) ("Using LRU heap disk replacement policy\n");
+		store_heap = new_heap(10000, HeapKeyGen_StoreEntry_LRU);
+	    }
+	} else {
+	    debug(20, 1) ("Unrecognized replacement_policy; using GDSF\n");
+	    store_heap = new_heap(10000, HeapKeyGen_StoreEntry_GDSF);
+	}
+    } else {
+	debug(20, 1) ("Using default disk replacement policy (GDSF)\n");
+	store_heap = new_heap(10000, HeapKeyGen_StoreEntry_GDSF);
     }
-    storeDirOpenSwapLogs();
+#else
     store_list.head = store_list.tail = NULL;
     inmem_list.head = inmem_list.tail = NULL;
+#endif
     stackInit(&LateReleaseStack);
     eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
+    storeDirInit();
     storeRebuildStart();
     cachemgrRegister("storedir",
 	"Store Directory Stats",
@@ -962,7 +1138,6 @@
 	    (float) Config.Swap.highWaterMark) / (float) 100);
     store_swap_low = (long) (((float) Config.Swap.maxSize *
 	    (float) Config.Swap.lowWaterMark) / (float) 100);
-    store_swap_mid = (store_swap_high >> 1) + (store_swap_low >> 1);
     store_pages_max = Config.memMaxSize / SM_PAGE_SIZE;
 }
 
@@ -986,12 +1161,21 @@
 	return 1;
     if (EBIT_TEST(e->flags, ENTRY_NEGCACHED) && squid_curtime >= e->expires)
 	return 1;
+#if HEAP_REPLACEMENT
+    /*
+     * With HEAP_REPLACEMENT we are not using the LRU reference age, the heap
+     * controls the replacement of objects.
+     */
+    return 1;
+#else
     if (squid_curtime - e->lastref > storeExpiredReferenceAge())
 	return 1;
     return 0;
+#endif
 }
 
-/* 
+#if !HEAP_REPLACEMENT
+/*
  * storeExpiredReferenceAge
  *
  * The LRU age is scaled exponentially between 1 minute and
@@ -1018,6 +1202,7 @@
 	age = 31536000;
     return age;
 }
+#endif
 
 void
 storeNegativeCache(StoreEntry * e)
@@ -1032,7 +1217,7 @@
     hashFreeItems(store_table, destroy_StoreEntry);
     hashFreeMemory(store_table);
     store_table = NULL;
-#if USE_CACHE_DIGEST
+#if USE_CACHE_DIGESTS
     if (store_digest)
 	cacheDigestDestroy(store_digest);
 #endif
@@ -1063,11 +1248,26 @@
 void
 storeTimestampsSet(StoreEntry * entry)
 {
-    time_t served_date = -1;
     const HttpReply *reply = entry->mem_obj->reply;
-    served_date = reply->date;
-    if (served_date < 0)
+    time_t served_date = reply->date;
+    int age = httpHeaderGetInt(&reply->header, HDR_AGE);
+    /*
+     * The timestamp calculations below tries to mimic the properties
+     * of the age calculation in RFC2616 section 13.2.3. The implementaion
+     * isn't complete, and the most notable exception from the RFC is that
+     * this does not account for response_delay, but it probably does
+     * not matter much as this is calculated immediately when the headers
+     * are received, not when the whole response has been received.
+     */
+    /* make sure that 0 <= served_date <= squid_curtime */
+    if (served_date < 0 || served_date > squid_curtime)
 	served_date = squid_curtime;
+    /*
+     * Compensate with Age header if origin server clock is ahead of us
+     * and there is a cache in between us and the origin server
+     */
+    if (age > squid_curtime - served_date)
+	served_date = squid_curtime - age;
     entry->expires = reply->expires;
     entry->lastmod = reply->last_modified;
     entry->timestamp = served_date;
@@ -1111,8 +1311,6 @@
 	mem->clients);
     debug(20, 1) ("MemObject->nclients: %d\n",
 	mem->nclients);
-    debug(20, 1) ("MemObject->swapout.fd: %d\n",
-	mem->swapout.fd);
     debug(20, 1) ("MemObject->reply: %p\n",
 	mem->reply);
     debug(20, 1) ("MemObject->request: %p\n",
@@ -1123,7 +1321,7 @@
 }
 
 void
-storeEntryDump(StoreEntry * e, int l)
+storeEntryDump(const StoreEntry * e, int l)
 {
     debug(20, l) ("StoreEntry->key: %s\n", storeKeyText(e->key));
     debug(20, l) ("StoreEntry->next: %p\n", e->next);
@@ -1143,7 +1341,9 @@
     debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);
 }
 
-/* NOTE, this function assumes only two mem states */
+/*
+ * NOTE, this function assumes only two mem states
+ */
 void
 storeSetMemStatus(StoreEntry * e, int new_status)
 {
@@ -1153,10 +1353,35 @@
     assert(mem != NULL);
     if (new_status == IN_MEMORY) {
 	assert(mem->inmem_lo == 0);
+#if HEAP_REPLACEMENT
+	if (mem->node == NULL) {
+	    if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
+		debug(20, 4) ("storeSetMemStatus: not inserting special %s\n",
+		    mem->url);
+	    } else {
+		mem->node = heap_insert(inmem_heap, e);
+		debug(20, 4) ("storeSetMemStatus: inserted mem node %p\n",
+		    mem->node);
+	    }
+	}
+#else
 	dlinkAdd(e, &mem->lru, &inmem_list);
+#endif
 	hot_obj_count++;
     } else {
+#if HEAP_REPLACEMENT
+	/*
+	 * It's being removed from the memory heap; is it already gone?
+	 */
+	if (mem->node) {
+	    heap_delete(inmem_heap, mem->node);
+	    debug(20, 4) ("storeSetMemStatus: deleted mem node %p\n",
+		mem->node);
+	    mem->node = NULL;
+	}
+#else
 	dlinkDelete(&mem->lru, &inmem_list);
+#endif
 	hot_obj_count--;
     }
     e->mem_status = new_status;
@@ -1194,18 +1419,7 @@
 {
     EBIT_CLR(e->flags, DELAY_SENDING);
     InvokeHandlers(e);
-    storeCheckSwapOut(e);
-}
-
-void
-storeUnlinkFileno(int fileno)
-{
-    debug(20, 5) ("storeUnlinkFileno: %08X\n", fileno);
-#if USE_ASYNC_IO
-    safeunlink(storeSwapFullPath(fileno, NULL), 1);
-#else
-    unlinkdUnlink(storeSwapFullPath(fileno, NULL));
-#endif
+    storeSwapOut(e);
 }
 
 int
@@ -1238,9 +1452,21 @@
 {
     MemObject *mem = e->mem_obj;
     debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e));
-    assert(mem->swapout.fd == -1);
+    assert(mem->swapout.sio == NULL);
     stmemFree(&mem->data_hdr);
     mem->inmem_hi = mem->inmem_lo = 0;
     httpReplyDestroy(mem->reply);
     mem->reply = httpReplyCreate();
+    e->expires = e->lastmod = e->timestamp = -1;
 }
+
+#if HEAP_REPLACEMENT
+void
+storeHeapPositionUpdate(StoreEntry * e)
+{
+    if (e->node)
+	heap_update(store_heap, e->node, e);
+    if (e->mem_obj && e->mem_obj->node)
+	heap_update(inmem_heap, e->mem_obj->node, e);
+}
+#endif
Index: squid/src/store_client.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_client.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_client.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_client.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_client.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_client.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Client-Side Interface
  * AUTHOR: Duane Wessels
@@ -40,9 +40,8 @@
  *       'Body' refers to the swapfile body, which is the full
  *        HTTP reply (including HTTP headers and body).
  */
-static DRCB storeClientReadBody;
-static DRCB storeClientReadHeader;
-static SIH storeClientFileOpened;
+static STRCB storeClientReadBody;
+static STRCB storeClientReadHeader;
 static void storeClientCopy2(StoreEntry * e, store_client * sc);
 static void storeClientFileRead(store_client * sc);
 static EVH storeClientCopyEvent;
@@ -99,6 +98,14 @@
     else if (mem->nclients == 1)
 	return STORE_MEM_CLIENT;
     /*
+     * If there is no disk file to open yet, we must make this a
+     * mem client.  If we can't open the swapin file before writing
+     * to the client, there is no guarantee that we will be able
+     * to open it later when we really need it.
+     */
+    else if (e->swap_status == SWAPOUT_NONE)
+	return STORE_MEM_CLIENT;
+    /*
      * otherwise, make subsequent clients read from disk so they
      * can not delay the first, and vice-versa.
      */
@@ -116,13 +123,14 @@
     assert(mem);
     if (storeClientListSearch(mem, data) != NULL)
 	return;
+    e->refcount++;
     mem->nclients++;
     sc = memAllocate(MEM_STORE_CLIENT);
     cbdataAdd(sc, memFree, MEM_STORE_CLIENT);	/* sc is callback_data for file_read */
+    cbdataLock(data);		/* locked while we point to it */
     sc->callback_data = data;
     sc->seen_offset = 0;
     sc->copy_offset = 0;
-    sc->swapin_fd = -1;
     sc->flags.disk_io_pending = 0;
     sc->entry = e;
     sc->type = storeClientType(e);
@@ -232,14 +240,6 @@
      */
     if (storeClientNoMoreToSend(e, sc)) {
 	/* There is no more to send! */
-#if USE_ASYNC_IO
-	if (sc->flags.disk_io_pending) {
-	    if (sc->swapin_fd >= 0)
-		aioCancel(sc->swapin_fd, NULL);
-	    else
-		aioCancel(-1, sc);
-	}
-#endif
 	sc->flags.disk_io_pending = 0;
 	sc->callback = NULL;
 	callback(sc->callback_data, sc->copy_buf, 0);
@@ -250,18 +250,10 @@
 	/* What the client wants is in memory */
 	debug(20, 3) ("storeClientCopy2: Copying from memory\n");
 	sz = stmemCopy(&mem->data_hdr, sc->copy_offset, sc->copy_buf, sc->copy_size);
-#if USE_ASYNC_IO
-	if (sc->flags.disk_io_pending) {
-	    if (sc->swapin_fd >= 0)
-		aioCancel(sc->swapin_fd, NULL);
-	    else
-		aioCancel(-1, sc);
-	}
-#endif
 	sc->flags.disk_io_pending = 0;
 	sc->callback = NULL;
 	callback(sc->callback_data, sc->copy_buf, sz);
-    } else if (sc->swapin_fd < 0) {
+    } else if (sc->swapin_sio == NULL) {
 	debug(20, 3) ("storeClientCopy2: Need to open swap in file\n");
 	assert(sc->type == STORE_DISK_CLIENT);
 	/* gotta open the swapin file */
@@ -271,15 +263,22 @@
 	    callback(sc->callback_data, sc->copy_buf, -1);
 	} else if (!sc->flags.disk_io_pending) {
 	    sc->flags.disk_io_pending = 1;
-	    storeSwapInStart(e, storeClientFileOpened, sc);
+	    storeSwapInStart(sc);
+	    if (NULL == sc->swapin_sio) {
+		sc->flags.disk_io_pending = 0;
+		sc->callback = NULL;
+		callback(sc->callback_data, sc->copy_buf, -1);
+	    } else {
+		storeClientFileRead(sc);
+	    }
 	} else {
 	    debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n");
 	}
     } else {
-	debug(20, 3) ("storeClientCopy: reading from disk FD %d\n",
-	    sc->swapin_fd);
+	debug(20, 3) ("storeClientCopy: reading from STORE\n");
 	assert(sc->type == STORE_DISK_CLIENT);
 	if (!sc->flags.disk_io_pending) {
+	    sc->flags.disk_io_pending = 1;
 	    storeClientFileRead(sc);
 	} else {
 	    debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n");
@@ -290,31 +289,12 @@
 }
 
 static void
-storeClientFileOpened(int fd, void *data)
-{
-    store_client *sc = data;
-    STCB *callback = sc->callback;
-    if (fd < 0) {
-	debug(20, 3) ("storeClientFileOpened: failed\n");
-	sc->flags.disk_io_pending = 0;
-	sc->callback = NULL;
-	callback(sc->callback_data, sc->copy_buf, -1);
-	return;
-    }
-    sc->swapin_fd = fd;
-    storeClientFileRead(sc);
-}
-
-static void
 storeClientFileRead(store_client * sc)
 {
     MemObject *mem = sc->entry->mem_obj;
     assert(sc->callback != NULL);
-#ifdef OPTIMISTIC_IO
-    sc->flags.disk_io_pending = 1;
-#endif
     if (mem->swap_hdr_sz == 0) {
-	file_read(sc->swapin_fd,
+	storeRead(sc->swapin_sio,
 	    sc->copy_buf,
 	    sc->copy_size,
 	    0,
@@ -322,21 +302,18 @@
 	    sc);
     } else {
 	if (sc->entry->swap_status == SWAPOUT_WRITING)
-	    assert(mem->swapout.done_offset > sc->copy_offset + mem->swap_hdr_sz);
-	file_read(sc->swapin_fd,
+	    assert(storeOffset(mem->swapout.sio) > sc->copy_offset + mem->swap_hdr_sz);
+	storeRead(sc->swapin_sio,
 	    sc->copy_buf,
 	    sc->copy_size,
 	    sc->copy_offset + mem->swap_hdr_sz,
 	    storeClientReadBody,
 	    sc);
     }
-#ifndef OPTIMISTIC_IO
-    sc->flags.disk_io_pending = 1;
-#endif
 }
 
 static void
-storeClientReadBody(int fd, const char *buf, int len, int flagnotused, void *data)
+storeClientReadBody(void *data, const char *buf, ssize_t len)
 {
     store_client *sc = data;
     MemObject *mem = sc->entry->mem_obj;
@@ -344,15 +321,15 @@
     assert(sc->flags.disk_io_pending);
     sc->flags.disk_io_pending = 0;
     assert(sc->callback != NULL);
-    debug(20, 3) ("storeClientReadBody: FD %d, len %d\n", fd, len);
+    debug(20, 3) ("storeClientReadBody: len %d\n", len);
     if (sc->copy_offset == 0 && len > 0 && mem->reply->sline.status == 0)
-	httpReplyParse(mem->reply, sc->copy_buf);
+	httpReplyParse(mem->reply, sc->copy_buf, headersEnd(sc->copy_buf, len));
     sc->callback = NULL;
     callback(sc->callback_data, sc->copy_buf, len);
 }
 
 static void
-storeClientReadHeader(int fd, const char *buf, int len, int flagnotused, void *data)
+storeClientReadHeader(void *data, const char *buf, ssize_t len)
 {
     store_client *sc = data;
     StoreEntry *e = sc->entry;
@@ -362,17 +339,26 @@
     size_t body_sz;
     size_t copy_sz;
     tlv *tlv_list;
+    tlv *t;
+    int swap_object_ok = 1;
     assert(sc->flags.disk_io_pending);
     sc->flags.disk_io_pending = 0;
     assert(sc->callback != NULL);
-    debug(20, 3) ("storeClientReadHeader: FD %d, len %d\n", fd, len);
+    debug(20, 3) ("storeClientReadHeader: len %d\n", len);
     if (len < 0) {
-	debug(20, 3) ("storeClientReadHeader: FD %d: %s\n", fd, xstrerror());
+	debug(20, 3) ("storeClientReadHeader: %s\n", xstrerror());
 	sc->callback = NULL;
 	callback(sc->callback_data, sc->copy_buf, len);
 	return;
     }
     tlv_list = storeSwapMetaUnpack(buf, &swap_hdr_sz);
+    if (swap_hdr_sz > len) {
+	/* oops, bad disk file? */
+	debug(20, 1) ("storeClientReadHeader: header too small\n");
+	sc->callback = NULL;
+	callback(sc->callback_data, sc->copy_buf, -1);
+	return;
+    }
     if (tlv_list == NULL) {
 	debug(20, 1) ("storeClientReadHeader: failed to unpack meta data\n");
 	sc->callback = NULL;
@@ -380,10 +366,40 @@
 	return;
     }
     /*
-     * XXX Here we should check the meta data and make sure we got
-     * the right object.
+     * Check the meta data and make sure we got the right object.
      */
+    for (t = tlv_list; t; t = t->next) {
+	switch (t->type) {
+	case STORE_META_KEY:
+	    assert(t->length == MD5_DIGEST_CHARS);
+	    if (memcmp(t->value, e->key, MD5_DIGEST_CHARS))
+		debug(20, 1) ("WARNING: swapin MD5 mismatch\n");
+	    break;
+	case STORE_META_URL:
+	    if (NULL == mem->url)
+		(void) 0;	/* can't check */
+	    else if (0 == strcasecmp(mem->url, t->value))
+		(void) 0;	/* a match! */
+	    else {
+		debug(20, 1) ("storeClientReadHeader: URL mismatch\n");
+		debug(20, 1) ("\t{%s} != {%s}\n", t->value, mem->url);
+		swap_object_ok = 0;
+		break;
+	    }
+	    break;
+	case STORE_META_STD:
+	    break;
+	default:
+	    debug(20, 1) ("WARNING: got unused STORE_META type %d\n", t->type);
+	    break;
+	}
+    }
     storeSwapTLVFree(tlv_list);
+    if (!swap_object_ok) {
+	sc->callback = NULL;
+	callback(sc->callback_data, sc->copy_buf, -1);
+	return;
+    }
     mem->swap_hdr_sz = swap_hdr_sz;
     mem->object_sz = e->swap_file_sz - swap_hdr_sz;
     /*
@@ -400,7 +416,8 @@
 	    copy_sz);
 	xmemmove(sc->copy_buf, sc->copy_buf + swap_hdr_sz, copy_sz);
 	if (sc->copy_offset == 0 && len > 0 && mem->reply->sline.status == 0)
-	    httpReplyParse(mem->reply, sc->copy_buf);
+	    httpReplyParse(mem->reply, sc->copy_buf,
+		headersEnd(sc->copy_buf, copy_sz));
 	sc->callback = NULL;
 	callback(sc->callback_data, sc->copy_buf, copy_sz);
 	return;
@@ -451,25 +468,23 @@
     mem->nclients--;
     sc->flags.disk_io_pending = 0;
     if (e->store_status == STORE_OK && e->swap_status != SWAPOUT_DONE)
-	storeCheckSwapOut(e);
-    if (sc->swapin_fd > -1) {
-	file_close(sc->swapin_fd);
-	store_open_disk_fd--;
+	storeSwapOut(e);
+    if (sc->swapin_sio) {
+	storeClose(sc->swapin_sio);
+	sc->swapin_sio = NULL;
     }
-#if USE_ASYNC_IO
-    else
-	aioCancel(-1, sc);
-#endif
     if ((callback = sc->callback) != NULL) {
 	/* callback with ssize = -1 to indicate unexpected termination */
 	debug(20, 3) ("storeUnregister: store_client for %s has a callback\n",
 	    mem->url);
 	sc->callback = NULL;
-	callback(sc->callback_data, sc->copy_buf, -1);
+	if (cbdataValid(sc->callback_data))
+	    callback(sc->callback_data, sc->copy_buf, -1);
     }
 #if DELAY_POOLS
     delayUnregisterDelayIdPtr(&sc->delay_id);
 #endif
+    cbdataUnlock(sc->callback_data);	/* we're done with it now */
     cbdataFree(sc);
     assert(e->lock_count > 0);
     if (mem->nclients == 0)
Index: squid/src/store_digest.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_digest.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_digest.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_digest.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: store_digest.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_digest.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 71    Store Digest Manager
  * AUTHOR: Alex Rousskov
@@ -66,21 +66,6 @@
     int rej_coll_count;		/* #not accepted entries that collided with existing ones */
 } StoreDigestStats;
 
-/*
- * local constants (many of these are good candidates for SquidConfig
- */
-
-/* #bits per entry in store digest */
-static const int StoreDigestBitsPerEntry = 5;
-/* how often we want to rebuild the digest, in seconds */
-static const time_t StoreDigestRebuildPeriod = 60 * 60;
-/* how often we want to rewrite the digest after rebuild, in seconds */
-static const int StoreDigestRewritePeriod = 60 * 60;
-/* how many bytes to swap out at a time */
-static const int StoreDigestSwapOutChunkSize = SM_PAGE_SIZE;
-/* portion (0,1] of a hash table to be rescanned at a time */
-static const double StoreDigestRebuildChunkPercent = 0.10;
-
 /* local vars */
 static StoreDigestState sd_state;
 static StoreDigestStats sd_stats;
@@ -110,9 +95,15 @@
 {
 #if USE_CACHE_DIGESTS
     const int cap = storeDigestCalcCap();
-    store_digest = cacheDigestCreate(cap, StoreDigestBitsPerEntry);
+
+    if (!Config.onoff.digest_generation) {
+	store_digest = NULL;
+	debug(71, 3) ("Local cache digest generation disabled\n");
+	return;
+    }
+    store_digest = cacheDigestCreate(cap, Config.digest.bits_per_entry);
     debug(71, 1) ("Local cache digest enabled; rebuild/rewrite every %d/%d sec\n",
-	StoreDigestRebuildPeriod, StoreDigestRewritePeriod);
+	Config.digest.rebuild_period, Config.digest.rewrite_period);
     memset(&sd_state, 0, sizeof(sd_state));
     cachemgrRegister("store_digest", "Store Digest",
 	storeDigestReport, 0, 1);
@@ -127,8 +118,10 @@
 storeDigestNoteStoreReady(void)
 {
 #if USE_CACHE_DIGESTS
-    storeDigestRebuildStart(NULL);
-    storeDigestRewriteStart(NULL);
+    if (Config.onoff.digest_generation) {
+	storeDigestRebuildStart(NULL);
+	storeDigestRewriteStart(NULL);
+    }
 #endif
 }
 
@@ -136,6 +129,9 @@
 storeDigestDel(const StoreEntry * entry)
 {
 #if USE_CACHE_DIGESTS
+    if (!Config.onoff.digest_generation) {
+	return;
+    }
     assert(entry && store_digest);
     debug(71, 6) ("storeDigestDel: checking entry, key: %s\n",
 	storeKeyText(entry->key));
@@ -158,6 +154,9 @@
 storeDigestReport(StoreEntry * e)
 {
 #if USE_CACHE_DIGESTS
+    if (!Config.onoff.digest_generation) {
+	return;
+    }
     if (store_digest) {
 	cacheDigestReport(store_digest, "store", e);
 	storeAppendPrintf(e, "\t added: %d rejected: %d ( %.2f %%) del-ed: %d\n",
@@ -217,9 +216,9 @@
     }
     /* still here? check staleness */
     /* Note: We should use the time of the next rebuild, not (cur_time+period) */
-    if (refreshCheckDigest(e, StoreDigestRebuildPeriod)) {
+    if (refreshCheckDigest(e, Config.digest.rebuild_period)) {
 	debug(71, 6) ("storeDigestAdd: entry expires within %d secs, ignoring\n",
-	    StoreDigestRebuildPeriod);
+	    Config.digest.rebuild_period);
 	return 0;
     }
     /* idea: how about also skipping very fresh (thus, potentially unstable) 
@@ -288,7 +287,8 @@
     sd_state.rebuild_lock = 0;
     sd_state.rebuild_count++;
     debug(71, 2) ("storeDigestRebuildFinish: done.\n");
-    eventAdd("storeDigestRebuildStart", storeDigestRebuildStart, NULL, (double) StoreDigestRebuildPeriod, 1);
+    eventAdd("storeDigestRebuildStart", storeDigestRebuildStart, NULL, (double)
+	Config.digest.rebuild_period, 1);
     /* resume pending Rewrite if any */
     if (sd_state.rewrite_lock)
 	storeDigestRewriteResume();
@@ -298,7 +298,8 @@
 static void
 storeDigestRebuildStep(void *datanotused)
 {
-    int bcount = (int) ceil(store_hash_buckets * StoreDigestRebuildChunkPercent);
+    int bcount = (int) ceil((double) store_hash_buckets *
+	(double) Config.digest.rebuild_chunk_percentage / 100.0);
     assert(sd_state.rebuild_lock);
     if (sd_state.rebuild_offset + bcount > store_hash_buckets)
 	bcount = store_hash_buckets - sd_state.rebuild_offset;
@@ -366,7 +367,7 @@
     httpReplyReset(e->mem_obj->reply);
     httpReplySetHeaders(e->mem_obj->reply, 1.0, 200, "Cache Digest OK",
 	"application/cache-digest", store_digest->mask_size + sizeof(sd_state.cblock),
-	squid_curtime, squid_curtime + StoreDigestRewritePeriod);
+	squid_curtime, squid_curtime + Config.digest.rewrite_period);
     debug(71, 3) ("storeDigestRewrite: entry expires on %d (%+d)\n",
 	e->mem_obj->reply->expires, e->mem_obj->reply->expires - squid_curtime);
     storeBuffer(e);
@@ -396,7 +397,8 @@
     cbdataFree(sd_state.rewrite_lock);
     sd_state.rewrite_lock = e = NULL;
     sd_state.rewrite_count++;
-    eventAdd("storeDigestRewriteStart", storeDigestRewriteStart, NULL, (double) StoreDigestRewritePeriod, 1);
+    eventAdd("storeDigestRewriteStart", storeDigestRewriteStart, NULL, (double)
+	Config.digest.rewrite_period, 1);
     /* resume pending Rebuild if any */
     if (sd_state.rebuild_lock)
 	storeDigestRebuildResume();
@@ -407,7 +409,7 @@
 storeDigestSwapOutStep(void *data)
 {
     StoreEntry *e = data;
-    int chunk_size = StoreDigestSwapOutChunkSize;
+    int chunk_size = Config.digest.swapout_chunk_size;
     assert(e);
     assert(e == sd_state.rewrite_lock);
     /* _add_ check that nothing bad happened while we were waiting @?@ @?@ */
@@ -434,7 +436,8 @@
     sd_state.cblock.count = htonl(store_digest->count);
     sd_state.cblock.del_count = htonl(store_digest->del_count);
     sd_state.cblock.mask_size = htonl(store_digest->mask_size);
-    sd_state.cblock.bits_per_entry = (unsigned char) StoreDigestBitsPerEntry;
+    sd_state.cblock.bits_per_entry = (unsigned char)
+	Config.digest.bits_per_entry;
     sd_state.cblock.hash_func_count = (unsigned char) CacheDigestHashFuncCount;
     storeAppend(e, (char *) &sd_state.cblock, sizeof(sd_state.cblock));
 }
Index: squid/src/store_dir.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_dir.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_dir.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_dir.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_dir.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_dir.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 47    Store Directory Routines
  * AUTHOR: Duane Wessels
@@ -34,196 +34,45 @@
  */
 
 #include "squid.h"
-#if HAVE_STATVFS
-#if HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-#endif
-
-#define SWAP_DIR_SHIFT 24
-#define SWAP_FILE_MASK 0x00FFFFFF
-#define DefaultLevelOneDirs     16
-#define DefaultLevelTwoDirs     256
-
-static char *storeSwapSubDir(int dirn, int subdirn);
-static int storeDirSelectSwapDir(void);
-static int storeVerifyDirectory(const char *path);
-static int storeCreateDirectory(const char *path, int);
-static void storeCreateSwapSubDirs(int j);
-
-/* return full name to swapfile */
-char *
-storeSwapFullPath(int fn, char *fullpath)
-{
-    LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN);
-    int dirn = (fn >> SWAP_DIR_SHIFT) % Config.cacheSwap.n_configured;
-    int filn = fn & SWAP_FILE_MASK;
-    int L1 = Config.cacheSwap.swapDirs[dirn].l1;
-    int L2 = Config.cacheSwap.swapDirs[dirn].l2;
-    if (!fullpath)
-	fullpath = fullfilename;
-    fullpath[0] = '\0';
-    snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X/%08X",
-	Config.cacheSwap.swapDirs[dirn].path,
-	((filn / L2) / L2) % L1,
-	(filn / L2) % L2,
-	filn);
-    return fullpath;
-}
-
-static char *
-storeSwapSubDir(int dirn, int subdirn)
-{
-    LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN);
-    SwapDir *SD;
-    assert(0 <= dirn && dirn < Config.cacheSwap.n_configured);
-    SD = &Config.cacheSwap.swapDirs[dirn];
-    assert(0 <= subdirn && subdirn < SD->l1);
-    snprintf(fullfilename, SQUID_MAXPATHLEN, "%s/%02X",
-	Config.cacheSwap.swapDirs[dirn].path,
-	subdirn);
-    return fullfilename;
-}
-
-char *
-storeSwapSubSubDir(int fn, char *fullpath)
-{
-    LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN);
-    int dirn = (fn >> SWAP_DIR_SHIFT) % Config.cacheSwap.n_configured;
-    int filn = fn & SWAP_FILE_MASK;
-    int L1 = Config.cacheSwap.swapDirs[dirn].l1;
-    int L2 = Config.cacheSwap.swapDirs[dirn].l2;
-    if (!fullpath)
-	fullpath = fullfilename;
-    fullpath[0] = '\0';
-    snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",
-	Config.cacheSwap.swapDirs[dirn].path,
-	((filn / L2) / L2) % L1,
-	(filn / L2) % L2);
-    return fullpath;
-}
-
-/*
- * Does swapfile number 'fn' belong in cachedir #F0,
- * level1 dir #F1, level2 dir #F2?
- *
- * This is called by storeDirClean(), but placed here because
- * the algorithm needs to match storeSwapSubSubDir().
- *
- * Don't check that (fn >> SWAP_DIR_SHIFT) == F0 because
- * 'fn' may not have the directory bits set.
- */
-int
-storeFilenoBelongsHere(int fn, int F0, int F1, int F2)
-{
-    int D1, D2;
-    int L1, L2;
-    int filn = fn & SWAP_FILE_MASK;
-    assert(F0 < Config.cacheSwap.n_configured);
-    L1 = Config.cacheSwap.swapDirs[F0].l1;
-    L2 = Config.cacheSwap.swapDirs[F0].l2;
-    D1 = ((filn / L2) / L2) % L1;
-    if (F1 != D1)
-	return 0;
-    D2 = (filn / L2) % L2;
-    if (F2 != D2)
-	return 0;
-    return 1;
-}
-
-static int
-storeCreateDirectory(const char *path, int should_exist)
-{
-    int created = 0;
-    struct stat st;
-    getCurrentTime();
-    if (0 == stat(path, &st)) {
-	if (S_ISDIR(st.st_mode)) {
-	    debug(20, should_exist ? 3 : 1) ("%s exists\n", path);
-	} else {
-	    fatalf("Swap directory %s is not a directory.", path);
-	}
-    } else if (0 == mkdir(path, 0755)) {
-	debug(20, should_exist ? 1 : 3) ("%s created\n", path);
-	created = 1;
-    } else {
-	fatalf("Failed to make swap directory %s: %s",
-	    path, xstrerror());
-    }
-    return created;
-}
 
-static int
-storeVerifyDirectory(const char *path)
+const char *SwapDirType[] =
 {
-    struct stat sb;
-    if (stat(path, &sb) < 0) {
-	debug(20, 0) ("%s: %s\n", path, xstrerror());
-	return -1;
-    }
-    if (S_ISDIR(sb.st_mode) == 0) {
-	debug(20, 0) ("%s is not a directory\n", path);
-	return -1;
-    }
-    return 0;
-}
+    "ufs",
+    "!ERROR!"
+};
 
-/*
- * This function is called by storeInit().  If this returns < 0,
- * then Squid exits, complains about swap directories not
- * existing, and instructs the admin to run 'squid -z'
- */
-int
-storeVerifyCacheDirs(void)
+void
+storeDirInit(void)
 {
     int i;
-    int j;
-    const char *path;
+    SwapDir *sd;
     for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	path = Config.cacheSwap.swapDirs[i].path;
-	if (storeVerifyDirectory(path) < 0)
-	    return -1;
-	for (j = 0; j < Config.cacheSwap.swapDirs[i].l1; j++) {
-	    path = storeSwapSubDir(i, j);
-	    if (storeVerifyDirectory(path) < 0)
-		return -1;
-	}
+	sd = &Config.cacheSwap.swapDirs[i];
+	sd->init(sd);
     }
-    return 0;
 }
 
 void
 storeCreateSwapDirectories(void)
 {
     int i;
-    const char *path = NULL;
+    SwapDir *sd;
+    pid_t pid;
+    int status;
     for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	path = Config.cacheSwap.swapDirs[i].path;
-	debug(47, 3) ("Creating swap space in %s\n", path);
-	storeCreateDirectory(path, 0);
-	storeCreateSwapSubDirs(i);
-    }
-}
-
-static void
-storeCreateSwapSubDirs(int j)
-{
-    int i, k;
-    int should_exist;
-    SwapDir *SD = &Config.cacheSwap.swapDirs[j];
-    LOCAL_ARRAY(char, name, MAXPATHLEN);
-    for (i = 0; i < SD->l1; i++) {
-	snprintf(name, MAXPATHLEN, "%s/%02X", SD->path, i);
-	if (storeCreateDirectory(name, 0))
-	    should_exist = 0;
-	else
-	    should_exist = 1;
-	debug(47, 1) ("Making directories in %s\n", name);
-	for (k = 0; k < SD->l2; k++) {
-	    snprintf(name, MAXPATHLEN, "%s/%02X/%02X", SD->path, i, k);
-	    storeCreateDirectory(name, should_exist);
-	}
-    }
+	if (fork())
+	    continue;
+	sd = &Config.cacheSwap.swapDirs[i];
+	sd->newfs(sd);
+	exit(0);
+    }
+    do {
+#ifdef _SQUID_NEXT_
+	pid = wait3(&status, WNOHANG, NULL);
+#else
+	pid = waitpid(-1, &status, 0);
+#endif
+    } while (pid > 0 || (pid < 0 && errno == EINTR));
 }
 
 /*
@@ -318,7 +167,7 @@
 }
 
 int
-storeDirValidFileno(int fn)
+storeDirValidFileno(int fn, int flag)
 {
     int dirn = fn >> SWAP_DIR_SHIFT;
     int filn = fn & SWAP_FILE_MASK;
@@ -328,8 +177,13 @@
 	return 0;
     if (filn < 0)
 	return 0;
-    if (filn > Config.cacheSwap.swapDirs[dirn].map->max_n_files)
-	return 0;
+    /*
+     * If flag is set it means out-of-range file number should
+     * be considered invalid.
+     */
+    if (flag)
+	if (filn > Config.cacheSwap.swapDirs[dirn].map->max_n_files)
+	    return 0;
     return 1;
 }
 
@@ -398,9 +252,8 @@
 void
 storeDirSwapLog(const StoreEntry * e, int op)
 {
-    storeSwapLogData *s;
-    int dirn;
-    dirn = e->swap_file_number >> SWAP_DIR_SHIFT;
+    int dirn = e->swap_file_number >> SWAP_DIR_SHIFT;
+    SwapDir *sd;
     assert(dirn < Config.cacheSwap.n_configured);
     assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
     assert(e->swap_file_number >= 0);
@@ -414,156 +267,8 @@
 	swap_log_op_str[op],
 	storeKeyText(e->key),
 	e->swap_file_number);
-    s = xcalloc(1, sizeof(storeSwapLogData));
-    s->op = (char) op;
-    s->swap_file_number = e->swap_file_number;
-    s->timestamp = e->timestamp;
-    s->lastref = e->lastref;
-    s->expires = e->expires;
-    s->lastmod = e->lastmod;
-    s->swap_file_sz = e->swap_file_sz;
-    s->refcount = e->refcount;
-    s->flags = e->flags;
-    xmemcpy(s->key, e->key, MD5_DIGEST_CHARS);
-    file_write(Config.cacheSwap.swapDirs[dirn].swaplog_fd,
-	-1,
-	s,
-	sizeof(storeSwapLogData),
-	NULL,
-	NULL,
-	xfree);
-}
-
-char *
-storeDirSwapLogFile(int dirn, const char *ext)
-{
-    LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);
-    LOCAL_ARRAY(char, digit, 32);
-    if (Config.Log.swap) {
-	xstrncpy(path, Config.Log.swap, SQUID_MAXPATHLEN - 64);
-	strcat(path, ".");
-	snprintf(digit, 32, "%02d", dirn);
-	strncat(path, digit, 3);
-    } else {
-	xstrncpy(path, storeSwapDir(dirn), SQUID_MAXPATHLEN - 64);
-	strcat(path, "/swap.state");
-    }
-    if (ext)
-	strncat(path, ext, 16);
-    return path;
-}
-
-void
-storeDirOpenSwapLogs(void)
-{
-    int i;
-    char *path;
-    int fd;
-    SwapDir *SD;
-    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	SD = &Config.cacheSwap.swapDirs[i];
-	path = storeDirSwapLogFile(i, NULL);
-	fd = file_open(path, O_WRONLY | O_CREAT, NULL, NULL, NULL);
-	if (fd < 0) {
-	    debug(50, 1) ("%s: %s\n", path, xstrerror());
-	    fatal("storeDirOpenSwapLogs: Failed to open swap log.");
-	}
-	debug(47, 3) ("Cache Dir #%d log opened on FD %d\n", i, fd);
-	SD->swaplog_fd = fd;
-    }
-}
-
-void
-storeDirCloseSwapLogs(void)
-{
-    int i;
-    SwapDir *SD;
-    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	SD = &Config.cacheSwap.swapDirs[i];
-	if (SD->swaplog_fd < 0)	/* not open */
-	    continue;
-	file_close(SD->swaplog_fd);
-	debug(47, 3) ("Cache Dir #%d log closed on FD %d\n", i, SD->swaplog_fd);
-	SD->swaplog_fd = -1;
-    }
-}
-
-FILE *
-storeDirOpenTmpSwapLog(int dirn, int *clean_flag, int *zero_flag)
-{
-    char *swaplog_path = xstrdup(storeDirSwapLogFile(dirn, NULL));
-    char *clean_path = xstrdup(storeDirSwapLogFile(dirn, ".last-clean"));
-    char *new_path = xstrdup(storeDirSwapLogFile(dirn, ".new"));
-    struct stat log_sb;
-    struct stat clean_sb;
-    SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
-    FILE *fp;
-    int fd;
-    if (stat(swaplog_path, &log_sb) < 0) {
-	debug(47, 1) ("Cache Dir #%d: No log file\n", dirn);
-	safe_free(swaplog_path);
-	safe_free(clean_path);
-	safe_free(new_path);
-	return NULL;
-    }
-    *zero_flag = log_sb.st_size == 0 ? 1 : 0;
-    /* close the existing write-only FD */
-    if (SD->swaplog_fd >= 0)
-	file_close(SD->swaplog_fd);
-    /* open a write-only FD for the new log */
-    fd = file_open(new_path, O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL);
-    if (fd < 0) {
-	debug(50, 1) ("%s: %s\n", new_path, xstrerror());
-	fatal("storeDirOpenTmpSwapLog: Failed to open swap log.");
-    }
-    SD->swaplog_fd = fd;
-    /* open a read-only stream of the old log */
-    fp = fopen(swaplog_path, "r");
-    if (fp == NULL) {
-	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
-	fatal("Failed to open swap log for reading");
-    }
-    memset(&clean_sb, '\0', sizeof(struct stat));
-    if (stat(clean_path, &clean_sb) < 0)
-	*clean_flag = 0;
-    else if (clean_sb.st_mtime < log_sb.st_mtime)
-	*clean_flag = 0;
-    else
-	*clean_flag = 1;
-    safeunlink(clean_path, 1);
-    safe_free(swaplog_path);
-    safe_free(clean_path);
-    safe_free(new_path);
-    return fp;
-}
-
-void
-storeDirCloseTmpSwapLog(int dirn)
-{
-    char *swaplog_path = xstrdup(storeDirSwapLogFile(dirn, NULL));
-    char *new_path = xstrdup(storeDirSwapLogFile(dirn, ".new"));
-    SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
-    int fd;
-    file_close(SD->swaplog_fd);
-#ifdef _SQUID_OS2_
-    if (unlink(swaplog_path) < 0) {
-	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
-	fatal("storeDirCloseTmpSwapLog: unlink failed");
-    }
-#endif
-    if (rename(new_path, swaplog_path) < 0) {
-	debug(50, 0) ("%s,%s: %s\n", new_path, swaplog_path, xstrerror());
-	fatal("storeDirCloseTmpSwapLog: rename failed");
-    }
-    fd = file_open(swaplog_path, O_WRONLY | O_CREAT, NULL, NULL, NULL);
-    if (fd < 0) {
-	debug(50, 1) ("%s: %s\n", swaplog_path, xstrerror());
-	fatal("storeDirCloseTmpSwapLog: Failed to open swap log.");
-    }
-    safe_free(swaplog_path);
-    safe_free(new_path);
-    SD->swaplog_fd = fd;
-    debug(47, 3) ("Cache Dir #%d log opened on FD %d\n", dirn, fd);
+    sd = &Config.cacheSwap.swapDirs[dirn];
+    sd->log.write(sd, e, op);
 }
 
 void
@@ -582,11 +287,6 @@
 void
 storeDirStats(StoreEntry * sentry)
 {
-    int i;
-    SwapDir *SD;
-#if HAVE_STATVFS
-    struct statvfs sfs;
-#endif
     storeAppendPrintf(sentry, "Store Directory Statistics:\n");
     storeAppendPrintf(sentry, "Store Entries          : %d\n",
 	memInUse(MEM_STOREENTRY));
@@ -597,40 +297,7 @@
     storeAppendPrintf(sentry, "Current Capacity       : %d%% used, %d%% free\n",
 	percent((int) store_swap_size, (int) Config.Swap.maxSize),
 	percent((int) (Config.Swap.maxSize - store_swap_size), (int) Config.Swap.maxSize));
-    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	SD = &Config.cacheSwap.swapDirs[i];
-	storeAppendPrintf(sentry, "\n");
-	storeAppendPrintf(sentry, "Store Directory #%d: %s\n", i, SD->path);
-	storeAppendPrintf(sentry, "First level subdirectories: %d\n", SD->l1);
-	storeAppendPrintf(sentry, "Second level subdirectories: %d\n", SD->l2);
-	storeAppendPrintf(sentry, "Maximum Size: %d KB\n", SD->max_size);
-	storeAppendPrintf(sentry, "Current Size: %d KB\n", SD->cur_size);
-	storeAppendPrintf(sentry, "Percent Used: %0.2f%%\n",
-	    100.0 * SD->cur_size / SD->max_size);
-	storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n",
-	    SD->map->n_files_in_map, SD->map->max_n_files,
-	    percent(SD->map->n_files_in_map, SD->map->max_n_files));
-#if HAVE_STATVFS
-#define fsbtoblk(num, fsbs, bs) \
-        (((fsbs) != 0 && (fsbs) < (bs)) ? \
-                (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
-	if (!statvfs(SD->path, &sfs)) {
-	    storeAppendPrintf(sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n",
-		fsbtoblk((sfs.f_blocks - sfs.f_bfree), sfs.f_frsize, 1024),
-		fsbtoblk(sfs.f_blocks, sfs.f_frsize, 1024),
-		percent(sfs.f_blocks - sfs.f_bfree, sfs.f_blocks));
-	    storeAppendPrintf(sentry, "Filesystem Inodes in use: %d/%d (%d%%)\n",
-		sfs.f_files - sfs.f_ffree, sfs.f_files,
-		percent(sfs.f_files - sfs.f_ffree, sfs.f_files));
-	}
-#endif
-	storeAppendPrintf(sentry, "Flags:");
-	if (SD->flags.selected)
-	    storeAppendPrintf(sentry, " SELECTED");
-	if (SD->flags.read_only)
-	    storeAppendPrintf(sentry, " READ-ONLY");
-	storeAppendPrintf(sentry, "\n");
-    }
+    storeUfsDirStats(sentry);	/* XXX */
 }
 
 int
@@ -643,6 +310,53 @@
     return n;
 }
 
+void
+storeDirConfigure(void)
+{
+    SwapDir *SD;
+    int i;
+    Config.Swap.maxSize = 0;
+    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
+	SD = &Config.cacheSwap.swapDirs[i];;
+	Config.Swap.maxSize += SD->max_size;
+	if (NULL == SD->map)
+	    SD->map = file_map_create();
+    }
+}
+
+void
+storeDirDiskFull(int fn)
+{
+    int dirn = fn >> SWAP_DIR_SHIFT;
+    SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
+    assert(0 <= dirn && dirn < Config.cacheSwap.n_configured);
+    SD->max_size = SD->cur_size;
+    debug(20, 1) ("WARNING: Shrinking cache_dir #%d to %d KB\n",
+	dirn, SD->cur_size);
+}
+
+void
+storeDirOpenSwapLogs(void)
+{
+    int dirn;
+    SwapDir *sd;
+    for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) {
+	sd = &Config.cacheSwap.swapDirs[dirn];
+	sd->log.open(sd);
+    }
+}
+
+void
+storeDirCloseSwapLogs(void)
+{
+    int dirn;
+    SwapDir *sd;
+    for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) {
+	sd = &Config.cacheSwap.swapDirs[dirn];
+	sd->log.close(sd);
+    }
+}
+
 /*
  *  storeDirWriteCleanLogs
  * 
@@ -653,62 +367,45 @@
 storeDirWriteCleanLogs(int reopen)
 {
     StoreEntry *e = NULL;
-    int *fd;
     int n = 0;
-    time_t start, stop, r;
-    struct stat sb;
-    char **cur;
-    char **new;
-    char **cln;
+    struct timeval start;
+    double dt;
+    SwapDir *sd;
     int dirn;
     int N = Config.cacheSwap.n_configured;
+#if HEAP_REPLACEMENT
+    int node;
+#else
     dlink_node *m;
-    char **outbuf;
-    off_t *outbufoffset;
-    storeSwapLogData s;
-    size_t ss = sizeof(storeSwapLogData);
-    if (store_rebuilding) {
+#endif
+    if (store_dirs_rebuilding) {
 	debug(20, 1) ("Not currently OK to rewrite swap log.\n");
 	debug(20, 1) ("storeDirWriteCleanLogs: Operation aborted.\n");
 	return 0;
     }
     debug(20, 1) ("storeDirWriteCleanLogs: Starting...\n");
-    start = squid_curtime;
-    fd = xcalloc(N, sizeof(int));
-    cur = xcalloc(N, sizeof(char *));
-    new = xcalloc(N, sizeof(char *));
-    cln = xcalloc(N, sizeof(char *));
-    for (dirn = 0; dirn < N; dirn++) {
-	fd[dirn] = -1;
-	cur[dirn] = xstrdup(storeDirSwapLogFile(dirn, NULL));
-	new[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".clean"));
-	cln[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".last-clean"));
-	unlink(new[dirn]);
-	unlink(cln[dirn]);
-	fd[dirn] = file_open(new[dirn],
-	    O_WRONLY | O_CREAT | O_TRUNC,
-	    NULL,
-	    NULL,
-	    NULL);
-	if (fd[dirn] < 0) {
-	    debug(50, 0) ("storeDirWriteCleanLogs: %s: %s\n", new[dirn], xstrerror());
+    getCurrentTime();
+    start = current_time;
+    for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) {
+	sd = &Config.cacheSwap.swapDirs[dirn];
+	if (sd->log.clean.open(sd) < 0) {
+	    debug(20, 1) ("log.clean.open() failed for dir #%d\n", sd->index);
 	    continue;
 	}
-	debug(20, 3) ("storeDirWriteCleanLogs: opened %s, FD %d\n",
-	    new[dirn], fd[dirn]);
-#if HAVE_FCHMOD
-	if (stat(cur[dirn], &sb) == 0)
-	    fchmod(fd[dirn], sb.st_mode);
-#endif
-    }
-    outbuf = xcalloc(N, sizeof(char *));
-    outbufoffset = xcalloc(N, sizeof(*outbufoffset));
-    for (dirn = 0; dirn < N; dirn++) {
-	outbuf[dirn] = xcalloc(CLEAN_BUF_SZ, 1);
-	outbufoffset[dirn] = 0;
     }
-    for (m = store_list.tail; m; m = m->prev) {
+#if HEAP_REPLACEMENT
+    if (NULL == store_heap)
+	return 0;
+    for (node = 0; node < heap_nodes(store_heap); node++)
+#else
+    for (m = store_list.tail; m; m = m->prev)
+#endif
+    {
+#if HEAP_REPLACEMENT
+	e = (StoreEntry *) heap_peep(store_heap, node);
+#else
 	e = m->data;
+#endif
 	if (e->swap_file_number < 0)
 	    continue;
 	if (e->swap_status != SWAPOUT_DONE)
@@ -722,35 +419,10 @@
 	if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
 	    continue;
 	dirn = storeDirNumber(e->swap_file_number);
-	assert(dirn < N);
-	if (fd[dirn] < 0)
+	sd = &Config.cacheSwap.swapDirs[dirn];
+	if (NULL == sd->log.clean.write)
 	    continue;
-	memset(&s, '\0', ss);
-	s.op = (char) SWAP_LOG_ADD;
-	s.swap_file_number = e->swap_file_number;
-	s.timestamp = e->timestamp;
-	s.lastref = e->lastref;
-	s.expires = e->expires;
-	s.lastmod = e->lastmod;
-	s.swap_file_sz = e->swap_file_sz;
-	s.refcount = e->refcount;
-	s.flags = e->flags;
-	xmemcpy(&s.key, e->key, MD5_DIGEST_CHARS);
-	xmemcpy(outbuf[dirn] + outbufoffset[dirn], &s, ss);
-	outbufoffset[dirn] += ss;
-	/* buffered write */
-	if (outbufoffset[dirn] + ss > CLEAN_BUF_SZ) {
-	    if (write(fd[dirn], outbuf[dirn], outbufoffset[dirn]) < 0) {
-		debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n",
-		    new[dirn], xstrerror());
-		debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n");
-		file_close(fd[dirn]);
-		fd[dirn] = -1;
-		unlink(new[dirn]);
-		continue;
-	    }
-	    outbufoffset[dirn] = 0;
-	}
+	sd->log.clean.write(e, sd);
 	if ((++n & 0xFFFF) == 0) {
 	    getCurrentTime();
 	    debug(20, 1) ("  %7d entries written so far.\n", n);
@@ -758,112 +430,18 @@
     }
     /* flush */
     for (dirn = 0; dirn < N; dirn++) {
-	if (outbufoffset[dirn] == 0)
-	    continue;
-	if (fd[dirn] < 0)
-	    continue;
-	if (write(fd[dirn], outbuf[dirn], outbufoffset[dirn]) < 0) {
-	    debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n",
-		new[dirn], xstrerror());
-	    debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n");
-	    file_close(fd[dirn]);
-	    fd[dirn] = -1;
-	    unlink(new[dirn]);
-	    continue;
-	}
-	safe_free(outbuf[dirn]);
-    }
-    safe_free(outbuf);
-    safe_free(outbufoffset);
-    /*
-     * You can't rename open files on Microsoft "operating systems"
-     * so we have to close before renaming.
-     */
-    storeDirCloseSwapLogs();
-    /* rename */
-    for (dirn = 0; dirn < N; dirn++) {
-	if (fd[dirn] < 0)
+	sd = &Config.cacheSwap.swapDirs[dirn];
+	if (NULL == sd->log.clean.write)
 	    continue;
-#ifdef _SQUID_OS2_
-	file_close(fd[dirn]);
-	fd[dirn] = -1;
-	if (unlink(cur[dirn]) < 0)
-	    debug(50, 0) ("storeDirWriteCleanLogs: unlinkd failed: %s, %s\n",
-		xstrerror(), cur[dirn]);
-#endif
-	if (rename(new[dirn], cur[dirn]) < 0) {
-	    debug(50, 0) ("storeDirWriteCleanLogs: rename failed: %s, %s -> %s\n",
-		xstrerror(), new[dirn], cur[dirn]);
-	}
+	sd->log.clean.write(NULL, sd);
     }
     if (reopen)
 	storeDirOpenSwapLogs();
-    stop = squid_curtime;
-    r = stop - start;
+    getCurrentTime();
+    dt = tvSubDsec(start, current_time);
     debug(20, 1) ("  Finished.  Wrote %d entries.\n", n);
-    debug(20, 1) ("  Took %d seconds (%6.1f entries/sec).\n",
-	r > 0 ? (int) r : 0,
-	(double) n / (r > 0 ? r : 1));
-    /* touch a timestamp file if we're not still validating */
-    if (!store_rebuilding) {
-	for (dirn = 0; dirn < N; dirn++) {
-	    if (fd[dirn] < 0)
-		continue;
-	    file_close(file_open(cln[dirn],
-		    O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL));
-	}
-    }
-    /* close */
-    for (dirn = 0; dirn < N; dirn++) {
-	safe_free(cur[dirn]);
-	safe_free(new[dirn]);
-	safe_free(cln[dirn]);
-	if (fd[dirn] < 0)
-	    continue;
-	file_close(fd[dirn]);
-	fd[dirn] = -1;
-    }
-    safe_free(cur);
-    safe_free(new);
-    safe_free(cln);
-    safe_free(fd);
+    debug(20, 1) ("  Took %3.1f seconds (%6.1f entries/sec).\n",
+	dt, (double) n / (dt > 0.0 ? dt : 1.0));
     return n;
 }
 #undef CLEAN_BUF_SZ
-
-void
-storeDirConfigure(void)
-{
-    SwapDir *SD;
-    int n;
-    int i;
-    fileMap *fm;
-    Config.Swap.maxSize = 0;
-    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	SD = &Config.cacheSwap.swapDirs[i];;
-	Config.Swap.maxSize += SD->max_size;
-	n = 2 * SD->max_size / Config.Store.avgObjectSize;
-	if (NULL == SD->map) {
-	    /* first time */
-	    SD->map = file_map_create(n);
-	} else if (n > SD->map->max_n_files) {
-	    /* it grew, need to expand */
-	    fm = file_map_create(n);
-	    filemapCopy(SD->map, fm);
-	    filemapFreeMemory(SD->map);
-	    SD->map = fm;
-	}
-	/* else it shrunk, and we leave the old one in place */
-    }
-}
-
-void
-storeDirDiskFull(int fn)
-{
-    int dirn = fn >> SWAP_DIR_SHIFT;
-    SwapDir *SD = &Config.cacheSwap.swapDirs[dirn];
-    assert(0 <= dirn && dirn < Config.cacheSwap.n_configured);
-    SD->max_size = SD->cur_size;
-    debug(20, 1) ("WARNING: Shrinking cache_dir #%d to %d KB\n",
-	dirn, SD->cur_size);
-}
Index: squid/src/store_dir_ufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/store_dir_ufs.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/src/store_dir_ufs.c	26 Jan 2000 03:25:01 -0000	1.1
+++ squid/src/store_dir_ufs.c	26 Jan 2000 03:25:01 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_dir_ufs.c,v 1.1 2000/01/26 03:25:01 hno Exp $
+ * $Id: store_dir_ufs.c,v 1.1.1.1 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 47    Store Directory Routines
  * AUTHOR: Duane Wessels
Index: squid/src/store_heap_replacement.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/store_heap_replacement.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/src/store_heap_replacement.c	26 Jan 2000 03:25:01 -0000	1.1
+++ squid/src/store_heap_replacement.c	26 Jan 2000 03:25:01 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_heap_replacement.c,v 1.1 2000/01/26 03:25:01 hno Exp $
+ * $Id: store_heap_replacement.c,v 1.1.1.1 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Heap-based replacement
  * AUTHOR: John Dilley
Index: squid/src/store_io_ufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/store_io_ufs.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/src/store_io_ufs.c	26 Jan 2000 03:25:01 -0000	1.1
+++ squid/src/store_io_ufs.c	26 Jan 2000 03:25:01 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_io_ufs.c,v 1.1 2000/01/26 03:25:01 hno Exp $
+ * $Id: store_io_ufs.c,v 1.1.1.1 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 79    Storage Manager UFS Interface
  * AUTHOR: Duane Wessels
Index: squid/src/store_key_md5.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_key_md5.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_key_md5.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_key_md5.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_key_md5.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_key_md5.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager MD5 Cache Keys
  * AUTHOR: Duane Wessels
@@ -142,15 +142,12 @@
 }
 
 int
-storeKeyHashBuckets(int nobj)
+storeKeyHashBuckets(int nbuckets)
 {
-    if (nobj < 0x2000)
-	return 0x2000;
-    if (nobj < 0x4000)
-	return 0x4000;
-    if (nobj < 0x8000)
-	return 0x8000;
-    return 0x10000;
+    int n = 0x2000;
+    while (n < nbuckets)
+	n <<= 1;
+    return n;
 }
 
 int
Index: squid/src/store_log.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_log.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/src/store_log.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/src/store_log.c	26 Jan 2000 03:25:01 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_log.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: store_log.c,v 1.1.1.2 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Logging Functions
  * AUTHOR: Duane Wessels
@@ -55,6 +55,8 @@
 	return;
     if (mem == NULL)
 	return;
+    if (EBIT_TEST(e->flags, ENTRY_DONT_LOG))
+	return;
     if (mem->log_url == NULL) {
 	debug(20, 1) ("storeLog: NULL log_url for %s\n", mem->url);
 	storeMemObjectDump(mem);
@@ -71,7 +73,7 @@
 	(int) reply->date,
 	(int) reply->last_modified,
 	(int) reply->expires,
-	strBuf(reply->content_type) ? strBuf(reply->content_type) : "unknown",
+	strLen(reply->content_type) ? strBuf(reply->content_type) : "unknown",
 	reply->content_length,
 	(int) (mem->inmem_hi - mem->reply->hdr_sz),
 	RequestMethodStr[mem->method],
@@ -111,14 +113,14 @@
 	i--;
 	snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-	rename(from, to);
+	xrename(from, to);
     }
     /* Rotate the current log to .0 */
     if (Config.Log.rotateNumber > 0) {
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-	rename(fname, to);
+	xrename(fname, to);
     }
-    storelog_fd = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL);
+    storelog_fd = file_open(fname, O_WRONLY | O_CREAT);
     if (storelog_fd < 0) {
 	debug(50, 0) ("storeLogRotate: %s: %s\n", fname, xstrerror());
 	debug(20, 1) ("Store logging disabled\n");
@@ -138,11 +140,7 @@
     if (strcmp(Config.Log.store, "none") == 0)
 	storelog_fd = -1;
     else
-	storelog_fd = file_open(Config.Log.store,
-	    O_WRONLY | O_CREAT,
-	    NULL,
-	    NULL,
-	    NULL);
+	storelog_fd = file_open(Config.Log.store, O_WRONLY | O_CREAT);
     if (storelog_fd < 0)
 	debug(20, 1) ("Store logging disabled\n");
 }
Index: squid/src/store_rebuild.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_rebuild.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_rebuild.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_rebuild.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_rebuild.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_rebuild.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Store Rebuild Routines
  * AUTHOR: Duane Wessels
@@ -35,551 +35,41 @@
 
 #include "squid.h"
 
-#define STORE_META_BUFSZ 4096
-
-
-typedef struct _rebuild_dir rebuild_dir;
-typedef int RBHD(rebuild_dir * d);
-
-struct _rebuild_dir {
-    int dirn;
-    int n_read;
-    FILE *log;
-    int speed;
-    int clean;
-    int curlvl1;
-    int curlvl2;
-    int flag;
-    int done;
-    int in_dir;
-    int fn;
-    struct dirent *entry;
-    DIR *td;
-    RBHD *rebuild_func;
-    rebuild_dir *next;
-    char fullpath[SQUID_MAXPATHLEN];
-    char fullfilename[SQUID_MAXPATHLEN];
-};
-
-struct storeRebuildState {
-    rebuild_dir *rebuild_dir;
-    int objcount;		/* # objects successfully reloaded */
-    int expcount;		/* # objects expired */
-    int linecount;		/* # lines parsed from cache logfile */
-    int statcount;		/* # entries from directory walking */
-    int clashcount;		/* # swapfile clashes avoided */
-    int dupcount;		/* # duplicates purged */
-    int cancelcount;		/* # SWAP_LOG_DEL objects purged */
-    int invalid;		/* # bad lines */
-    int badflags;		/* # bad e->flags */
-    int need_to_validate;
-    int bad_log_op;
-    int zero_object_sz;
-    time_t start;
-    time_t stop;
-} RebuildState;
-
-typedef struct valid_ctrl_t {
-    struct stat *sb;
-    StoreEntry *e;
-    STVLDCB *callback;
-    void *callback_data;
-} valid_ctrl_t;
-
-static RBHD storeRebuildFromDirectory;
-static RBHD storeRebuildFromSwapLog;
-static void storeRebuildComplete(void);
-static EVH storeRebuildADirectory;
-static int storeGetNextFile(rebuild_dir *, int *sfileno, int *size);
-static StoreEntry *storeAddDiskRestore(const cache_key * key,
-    int file_number,
-    size_t swap_file_sz,
-    time_t expires,
-    time_t timestamp,
-    time_t lastref,
-    time_t lastmod,
-    u_num32 refcount,
-    u_short flags,
-    int clean);
-static AIOCB storeValidateComplete;
+static struct _store_rebuild_data counts;
+static struct timeval rebuild_start;
+static void storeCleanup(void *);
 
 static int
-storeRebuildFromDirectory(rebuild_dir * d)
+storeCleanupDoubleCheck(const StoreEntry * e)
 {
-    LOCAL_ARRAY(char, hdr_buf, DISK_PAGE_SIZE);
-    StoreEntry *e = NULL;
-    StoreEntry tmpe;
-    cache_key key[MD5_DIGEST_CHARS];
-    int sfileno = 0;
-    int count;
-    int size;
+    /* XXX too UFS specific */
     struct stat sb;
-    int swap_hdr_len;
-    int fd = -1;
-    tlv *tlv_list;
-    tlv *t;
-    assert(d != NULL);
-    debug(20, 3) ("storeRebuildFromDirectory: DIR #%d\n", d->dirn);
-    for (count = 0; count < d->speed; count++) {
-	assert(fd == -1);
-	fd = storeGetNextFile(d, &sfileno, &size);
-	if (fd == -2) {
-	    debug(20, 1) ("storeRebuildFromDirectory: DIR #%d done!\n", d->dirn);
-	    storeDirCloseTmpSwapLog(d->dirn);
-	    store_rebuilding = 0;
-	    return -1;
-	} else if (fd < 0) {
-	    continue;
-	}
-	assert(fd > -1);
-	/* lets get file stats here */
-	if (fstat(fd, &sb) < 0) {
-	    debug(20, 1) ("storeRebuildFromDirectory: fstat(FD %d): %s\n",
-		fd, xstrerror());
-	    file_close(fd);
-	    store_open_disk_fd--;
-	    fd = -1;
-	    continue;
-	}
-	if ((++RebuildState.statcount & 0xFFFF) == 0)
-	    debug(20, 1) ("  %7d files opened so far.\n",
-		RebuildState.statcount);
-	debug(20, 9) ("file_in: fd=%d %08X\n", fd, sfileno);
-	Counter.syscalls.disk.reads++;
-	if (read(fd, hdr_buf, DISK_PAGE_SIZE) < 0) {
-	    debug(20, 1) ("storeRebuildFromDirectory: read(FD %d): %s\n",
-		fd, xstrerror());
-	    file_close(fd);
-	    store_open_disk_fd--;
-	    fd = -1;
-	    continue;
-	}
-	file_close(fd);
-	store_open_disk_fd--;
-	fd = -1;
-	swap_hdr_len = 0;
-#if USE_TRUNCATE_NOT_UNLINK
-	if (sb.st_size == 0)
-	    continue;
-#endif
-	tlv_list = storeSwapMetaUnpack(hdr_buf, &swap_hdr_len);
-	if (tlv_list == NULL) {
-	    debug(20, 1) ("storeRebuildFromDirectory: failed to get meta data\n");
-	    storeUnlinkFileno(sfileno);
-	    continue;
-	}
-	debug(20, 3) ("storeRebuildFromDirectory: successful swap meta unpacking\n");
-	memset(key, '\0', MD5_DIGEST_CHARS);
-	memset(&tmpe, '\0', sizeof(StoreEntry));
-	for (t = tlv_list; t; t = t->next) {
-	    switch (t->type) {
-	    case STORE_META_KEY:
-		assert(t->length == MD5_DIGEST_CHARS);
-		xmemcpy(key, t->value, MD5_DIGEST_CHARS);
-		break;
-	    case STORE_META_STD:
-		assert(t->length == STORE_HDR_METASIZE);
-		xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
-		break;
-	    default:
-		break;
-	    }
-	}
-	storeSwapTLVFree(tlv_list);
-	tlv_list = NULL;
-	if (storeKeyNull(key)) {
-	    debug(20, 1) ("storeRebuildFromDirectory: NULL key\n");
-	    storeUnlinkFileno(sfileno);
-	    continue;
-	}
-	tmpe.key = key;
-	/* check sizes */
-	if (tmpe.swap_file_sz == 0) {
-	    tmpe.swap_file_sz = sb.st_size;
-	} else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) {
-	    tmpe.swap_file_sz = sb.st_size;
-	} else if (tmpe.swap_file_sz != sb.st_size) {
-	    debug(20, 1) ("storeRebuildFromDirectory: SIZE MISMATCH %d!=%d\n",
-		tmpe.swap_file_sz, (int) sb.st_size);
-	    storeUnlinkFileno(sfileno);
-	    continue;
-	}
-	if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
-	    storeUnlinkFileno(sfileno);
-	    RebuildState.badflags++;
-	    continue;
-	}
-	e = storeGet(key);
-	if (e && e->lastref >= tmpe.lastref) {
-	    /* key already exists, current entry is newer */
-	    /* keep old, ignore new */
-	    RebuildState.dupcount++;
-	    continue;
-	} else if (NULL != e) {
-	    /* URL already exists, this swapfile not being used */
-	    /* junk old, load new */
-	    storeRelease(e);	/* release old entry */
-	    RebuildState.dupcount++;
-	}
-	RebuildState.objcount++;
-	storeEntryDump(&tmpe, 5);
-	e = storeAddDiskRestore(key,
-	    sfileno,
-	    tmpe.swap_file_sz,
-	    tmpe.expires,
-	    tmpe.timestamp,
-	    tmpe.lastref,
-	    tmpe.lastmod,
-	    tmpe.refcount,	/* refcount */
-	    tmpe.flags,		/* flags */
-	    d->clean);
-    }
-    return count;
-}
-
-static int
-storeRebuildFromSwapLog(rebuild_dir * d)
-{
-    StoreEntry *e = NULL;
-    storeSwapLogData s;
-    size_t ss = sizeof(storeSwapLogData);
-    int count;
-    int used;			/* is swapfile already in use? */
-    int disk_entry_newer;	/* is the log entry newer than current entry? */
-    double x;
-    assert(d != NULL);
-    /* load a number of objects per invocation */
-    for (count = 0; count < d->speed; count++) {
-	if (fread(&s, ss, 1, d->log) != 1) {
-	    debug(20, 1) ("Done reading Cache Dir #%d swaplog (%d entries)\n",
-		d->dirn, d->n_read);
-	    fclose(d->log);
-	    d->log = NULL;
-	    storeDirCloseTmpSwapLog(d->dirn);
-	    return -1;
-	}
-	d->n_read++;
-	if (s.op <= SWAP_LOG_NOP)
-	    continue;
-	if (s.op >= SWAP_LOG_MAX)
-	    continue;
-	s.swap_file_number = storeDirProperFileno(d->dirn, s.swap_file_number);
-	debug(20, 3) ("storeRebuildFromSwapLog: %s %s %08X\n",
-	    swap_log_op_str[(int) s.op],
-	    storeKeyText(s.key),
-	    s.swap_file_number);
-	if (s.op == SWAP_LOG_ADD) {
-	    (void) 0;
-	} else if (s.op == SWAP_LOG_DEL) {
-	    if ((e = storeGet(s.key)) != NULL) {
-		/*
-		 * Make sure we don't unlink the file, it might be
-		 * in use by a subsequent entry.  Also note that
-		 * we don't have to subtract from store_swap_size
-		 * because adding to store_swap_size happens in
-		 * the cleanup procedure.
-		 */
-		storeExpireNow(e);
-		storeReleaseRequest(e);
-		if (e->swap_file_number > -1) {
-		    storeDirMapBitReset(e->swap_file_number);
-		    e->swap_file_number = -1;
-		}
-		RebuildState.objcount--;
-		RebuildState.cancelcount++;
-	    }
-	    continue;
-	} else {
-	    x = log(++RebuildState.bad_log_op) / log(10.0);
-	    if (0.0 == x - (double) (int) x)
-		debug(20, 1) ("WARNING: %d invalid swap log entries found\n",
-		    RebuildState.bad_log_op);
-	    RebuildState.invalid++;
-	    continue;
-	}
-	if ((++RebuildState.linecount & 0xFFFF) == 0)
-	    debug(20, 1) ("  %7d Entries read so far.\n",
-		RebuildState.linecount);
-	if (!storeDirValidFileno(s.swap_file_number)) {
-	    RebuildState.invalid++;
-	    continue;
-	}
-	if (EBIT_TEST(s.flags, KEY_PRIVATE)) {
-	    RebuildState.badflags++;
-	    continue;
-	}
-	e = storeGet(s.key);
-	used = storeDirMapBitTest(s.swap_file_number);
-	/* If this URL already exists in the cache, does the swap log
-	 * appear to have a newer entry?  Compare 'lastref' from the
-	 * swap log to e->lastref. */
-	disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;
-	if (used && !disk_entry_newer) {
-	    /* log entry is old, ignore it */
-	    RebuildState.clashcount++;
-	    continue;
-	} else if (used && e && e->swap_file_number == s.swap_file_number) {
-	    /* swapfile taken, same URL, newer, update meta */
-	    if (e->store_status == STORE_OK) {
-		e->lastref = s.timestamp;
-		e->timestamp = s.timestamp;
-		e->expires = s.expires;
-		e->lastmod = s.lastmod;
-		e->flags = s.flags;
-		e->refcount += s.refcount;
-	    } else {
-		debug_trap("storeRebuildFromSwapLog: bad condition");
-		debug(20, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);
-	    }
-	    continue;
-	} else if (used) {
-	    /* swapfile in use, not by this URL, log entry is newer */
-	    /* This is sorta bad: the log entry should NOT be newer at this
-	     * point.  If the log is dirty, the filesize check should have
-	     * caught this.  If the log is clean, there should never be a
-	     * newer entry. */
-	    debug(20, 1) ("WARNING: newer swaplog entry for fileno %08X\n",
-		s.swap_file_number);
-	    /* I'm tempted to remove the swapfile here just to be safe,
-	     * but there is a bad race condition in the NOVM version if
-	     * the swapfile has recently been opened for writing, but
-	     * not yet opened for reading.  Because we can't map
-	     * swapfiles back to StoreEntrys, we don't know the state
-	     * of the entry using that file.  */
-	    /* We'll assume the existing entry is valid, probably because
-	     * were in a slow rebuild and the the swap file number got taken
-	     * and the validation procedure hasn't run. */
-	    assert(RebuildState.need_to_validate);
-	    RebuildState.clashcount++;
-	    continue;
-	} else if (e && !disk_entry_newer) {
-	    /* key already exists, current entry is newer */
-	    /* keep old, ignore new */
-	    RebuildState.dupcount++;
-	    continue;
-	} else if (e) {
-	    /* key already exists, this swapfile not being used */
-	    /* junk old, load new */
-	    storeExpireNow(e);
-	    storeReleaseRequest(e);
-	    if (e->swap_file_number > -1) {
-		storeDirMapBitReset(e->swap_file_number);
-		e->swap_file_number = -1;
-	    }
-	    RebuildState.dupcount++;
-	} else {
-	    /* URL doesnt exist, swapfile not in use */
-	    /* load new */
-	    (void) 0;
-	}
-	/* update store_swap_size */
-	RebuildState.objcount++;
-	e = storeAddDiskRestore(s.key,
-	    s.swap_file_number,
-	    s.swap_file_sz,
-	    s.expires,
-	    s.timestamp,
-	    s.lastref,
-	    s.lastmod,
-	    s.refcount,
-	    s.flags,
-	    d->clean);
-	storeDirSwapLog(e, SWAP_LOG_ADD);
-    }
-    return count;
-}
-
-static void
-storeRebuildADirectory(void *unused)
-{
-    int count;
-    rebuild_dir *d;
-    rebuild_dir **D;
-    if ((d = RebuildState.rebuild_dir) == NULL) {
-	storeRebuildComplete();
-	return;
-    }
-    count = d->rebuild_func(d);
-    RebuildState.rebuild_dir = d->next;
-    if (count < 0) {
-	xfree(d);
-    } else {
-	for (D = &RebuildState.rebuild_dir; *D; D = &(*D)->next);
-	*D = d;
-	d->next = NULL;
-    }
-    if (opt_foreground_rebuild)
-	storeRebuildADirectory(NULL);
+    int dirn = e->swap_file_number >> SWAP_DIR_SHIFT;
+    if (Config.cacheSwap.swapDirs[dirn].type == SWAPDIR_UFS)
+	(void) 0;
+    if (Config.cacheSwap.swapDirs[dirn].type == SWAPDIR_ASYNCUFS)
+	(void) 0;
     else
-	eventAdd("storeRebuild", storeRebuildADirectory, NULL, 0.0, 1);
-}
-
-#if TEMP_UNUSED_CODE
-static void
-storeConvertFile(const cache_key * key,
-    int file_number,
-    size_t swap_file_sz,
-    time_t expires,
-    time_t timestamp,
-    time_t lastref,
-    time_t lastmod,
-    u_short refcount,
-    u_short flags,
-    int clean)
-{
-    int fd_r, fd_w;
-    int hdr_len, x, y;
-    LOCAL_ARRAY(char, swapfilename, SQUID_MAXPATHLEN);
-    LOCAL_ARRAY(char, copybuf, DISK_PAGE_SIZE);
-    char *buf;
-    tlv *tlv_list;
-    StoreEntry e;
-    e.key = key;
-    e.swap_file_sz = swap_file_sz;
-    e.expires = expires;
-    e.lastref = lastref;
-    e.refcount = refcount;
-    e.flag = flags;
-    storeSwapFullPath(file_number, swapfilename);
-    fd_r = file_open(swapfilename, O_RDONLY, NULL, NULL, NULL);
-    if (fd_r < 0)
-	return;
-    safeunlink(swapfilename, 1);
-    fd_w = file_open(swapfilename, O_CREAT | O_WRONLY | O_TRUNC, NULL, NULL, NULL);
-    tlv_list = storeSwapMetaBuild(&e);
-    buf = storeSwapMetaPack(tlv_list, &hdr_len);
-    x = write(fd_w, buf, hdr_len);
-    while (x > 0) {
-	y = read(fd_r, copybuf, DISK_PAGE_SIZE);
-	x = write(fd_w, copybuf, y);
+	return 0;
+    if (stat(storeUfsFullPath(e->swap_file_number, NULL), &sb) < 0) {
+	debug(20, 0) ("storeCleanup: MISSING SWAP FILE\n");
+	debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);
+	debug(20, 0) ("storeCleanup: PATH %s\n",
+	    storeUfsFullPath(e->swap_file_number, NULL));
+	storeEntryDump(e, 0);
+	return -1;
+    }
+    if (e->swap_file_sz != sb.st_size) {
+	debug(20, 0) ("storeCleanup: SIZE MISMATCH\n");
+	debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);
+	debug(20, 0) ("storeCleanup: PATH %s\n",
+	    storeUfsFullPath(e->swap_file_number, NULL));
+	debug(20, 0) ("storeCleanup: ENTRY SIZE: %d, FILE SIZE: %d\n",
+	    e->swap_file_sz, (int) sb.st_size);
+	storeEntryDump(e, 0);
+	return -1;
     }
-    file_close(fd_r);
-    file_close(fd_w);
-    xfree(buf);
-    storeSwapTLVFree(tlv_list);
-}
-#endif
-
-static int
-storeGetNextFile(rebuild_dir * d, int *sfileno, int *size)
-{
-    int fd = -1;
-    int used = 0;
-    debug(20, 3) ("storeGetNextFile: flag=%d, %d: /%02X/%02X\n",
-	d->flag,
-	d->dirn,
-	d->curlvl1,
-	d->curlvl2);
-    if (d->done)
-	return -2;
-    while (fd < 0 && d->done == 0) {
-	fd = -1;
-	if (0 == d->flag) {	/* initialize, open first file */
-	    d->done = 0;
-	    d->curlvl1 = 0;
-	    d->curlvl2 = 0;
-	    d->in_dir = 0;
-	    d->flag = 1;
-	    assert(Config.cacheSwap.n_configured > 0);
-	}
-	if (0 == d->in_dir) {	/* we need to read in a new directory */
-	    snprintf(d->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",
-		Config.cacheSwap.swapDirs[d->dirn].path,
-		d->curlvl1, d->curlvl2);
-	    if (d->flag && d->td != NULL)
-		closedir(d->td);
-	    d->td = opendir(d->fullpath);
-	    if (d->td == NULL) {
-		debug(50, 1) ("storeGetNextFile: opendir: %s: %s\n",
-		    d->fullpath, xstrerror());
-	    } else {
-		d->entry = readdir(d->td);	/* skip . and .. */
-		d->entry = readdir(d->td);
-		if (d->entry == NULL && errno == ENOENT)
-		    debug(20, 1) ("storeGetNextFile: directory does not exist!.\n");
-		debug(20, 3) ("storeGetNextFile: Directory %s\n", d->fullpath);
-	    }
-	}
-	if (d->td != NULL && (d->entry = readdir(d->td)) != NULL) {
-	    d->in_dir++;
-	    if (sscanf(d->entry->d_name, "%x", &d->fn) != 1) {
-		debug(20, 3) ("storeGetNextFile: invalid %s\n",
-		    d->entry->d_name);
-		continue;
-	    }
-	    if (!storeFilenoBelongsHere(d->fn, d->dirn, d->curlvl1, d->curlvl2)) {
-		debug(20, 3) ("storeGetNextFile: %08X does not belong in %d/%d/%d\n",
-		    d->fn, d->dirn, d->curlvl1, d->curlvl2);
-		continue;
-	    }
-	    d->fn = storeDirProperFileno(d->dirn, d->fn);
-	    used = storeDirMapBitTest(d->fn);
-	    if (used) {
-		debug(20, 3) ("storeGetNextFile: Locked, continuing with next.\n");
-		continue;
-	    }
-	    snprintf(d->fullfilename, SQUID_MAXPATHLEN, "%s/%s",
-		d->fullpath, d->entry->d_name);
-	    debug(20, 3) ("storeGetNextFile: Opening %s\n", d->fullfilename);
-	    fd = file_open(d->fullfilename, O_RDONLY, NULL, NULL, NULL);
-	    if (fd < 0)
-		debug(50, 1) ("storeGetNextFile: %s: %s\n", d->fullfilename, xstrerror());
-	    continue;
-	    store_open_disk_fd++;
-	}
-	d->in_dir = 0;
-	if (++d->curlvl2 < Config.cacheSwap.swapDirs[d->dirn].l2)
-	    continue;
-	d->curlvl2 = 0;
-	if (++d->curlvl1 < Config.cacheSwap.swapDirs[d->dirn].l1)
-	    continue;
-	d->curlvl1 = 0;
-	d->done = 1;
-    }
-    *sfileno = d->fn;
-    return fd;
-}
-
-/* Add a new object to the cache with empty memory copy and pointer to disk
- * use to rebuild store from disk. */
-static StoreEntry *
-storeAddDiskRestore(const cache_key * key,
-    int file_number,
-    size_t swap_file_sz,
-    time_t expires,
-    time_t timestamp,
-    time_t lastref,
-    time_t lastmod,
-    u_num32 refcount,
-    u_short flags,
-    int clean)
-{
-    StoreEntry *e = NULL;
-    debug(20, 5) ("StoreAddDiskRestore: %s, fileno=%08X\n", storeKeyText(key), file_number);
-    /* if you call this you'd better be sure file_number is not 
-     * already in use! */
-    e = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);
-    e->store_status = STORE_OK;
-    storeSetMemStatus(e, NOT_IN_MEMORY);
-    e->swap_status = SWAPOUT_DONE;
-    e->swap_file_number = file_number;
-    e->swap_file_sz = swap_file_sz;
-    e->lock_count = 0;
-    e->refcount = 0;
-    e->lastref = lastref;
-    e->timestamp = timestamp;
-    e->expires = expires;
-    e->lastmod = lastmod;
-    e->refcount = refcount;
-    e->flags = flags;
-    EBIT_SET(e->flags, ENTRY_CACHABLE);
-    EBIT_CLR(e->flags, RELEASE_REQUEST);
-    EBIT_CLR(e->flags, KEY_PRIVATE);
-    e->ping_status = PING_NONE;
-    EBIT_CLR(e->flags, ENTRY_VALIDATED);
-    storeDirMapBitSet(e->swap_file_number);
-    storeHashInsert(e, key);	/* do it after we clear KEY_PRIVATE */
-    return e;
+    return 0;
 }
 
 static void
@@ -588,194 +78,104 @@
     static int bucketnum = -1;
     static int validnum = 0;
     static int store_errors = 0;
+    int validnum_start;
     StoreEntry *e;
     hash_link *link_ptr = NULL;
     hash_link *link_next = NULL;
-    if (++bucketnum >= store_hash_buckets) {
-	debug(20, 1) ("  Completed Validation Procedure\n");
-	debug(20, 1) ("  Validated %d Entries\n", validnum);
-	debug(20, 1) ("  store_swap_size = %dk\n", store_swap_size);
-	store_rebuilding = 0;
-	if (opt_store_doublecheck)
-	    assert(store_errors == 0);
-	if (store_digest)
-	    storeDigestNoteStoreReady();
-	return;
-    }
-    link_next = hash_get_bucket(store_table, bucketnum);
-    while (NULL != (link_ptr = link_next)) {
-	link_next = link_ptr->next;
-	e = (StoreEntry *) link_ptr;
-	if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
-	    continue;
-	/*
-	 * Calling storeRelease() has no effect because we're
-	 * still in 'store_rebuilding' state
-	 */
-	if (e->swap_file_number < 0)
-	    continue;
-	if (opt_store_doublecheck) {
-	    struct stat sb;
-	    if (stat(storeSwapFullPath(e->swap_file_number, NULL), &sb) < 0) {
-		store_errors++;
-		debug(20, 0) ("storeCleanup: MISSING SWAP FILE\n");
-		debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);
-		debug(20, 0) ("storeCleanup: PATH %s\n",
-		    storeSwapFullPath(e->swap_file_number, NULL));
-		storeEntryDump(e, 0);
+    validnum_start = validnum;
+    while (validnum - validnum_start < 50) {
+	if (++bucketnum >= store_hash_buckets) {
+	    debug(20, 1) ("  Completed Validation Procedure\n");
+	    debug(20, 1) ("  Validated %d Entries\n", validnum);
+	    debug(20, 1) ("  store_swap_size = %dk\n", store_swap_size);
+	    store_dirs_rebuilding--;
+	    assert(0 == store_dirs_rebuilding);
+	    if (opt_store_doublecheck)
+		assert(store_errors == 0);
+	    if (store_digest)
+		storeDigestNoteStoreReady();
+	    return;
+	}
+	link_next = hash_get_bucket(store_table, bucketnum);
+	while (NULL != (link_ptr = link_next)) {
+	    link_next = link_ptr->next;
+	    e = (StoreEntry *) link_ptr;
+	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
 		continue;
-	    }
-	    if (e->swap_file_sz != sb.st_size) {
-		store_errors++;
-		debug(20, 0) ("storeCleanup: SIZE MISMATCH\n");
-		debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);
-		debug(20, 0) ("storeCleanup: PATH %s\n",
-		    storeSwapFullPath(e->swap_file_number, NULL));
-		debug(20, 0) ("storeCleanup: ENTRY SIZE: %d, FILE SIZE: %d\n",
-		    e->swap_file_sz, (int) sb.st_size);
-		storeEntryDump(e, 0);
+	    /*
+	     * Calling storeRelease() has no effect because we're
+	     * still in 'store_rebuilding' state
+	     */
+	    if (e->swap_file_number < 0)
 		continue;
-	    }
+	    if (opt_store_doublecheck)
+		if (storeCleanupDoubleCheck(e))
+		    store_errors++;
+	    EBIT_SET(e->flags, ENTRY_VALIDATED);
+	    /*
+	     * Only set the file bit if we know its a valid entry
+	     * otherwise, set it in the validation procedure
+	     */
+	    storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);
+	    if ((++validnum & 0x3FFFF) == 0)
+		debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);
 	}
-	EBIT_SET(e->flags, ENTRY_VALIDATED);
-	/* Only set the file bit if we know its a valid entry */
-	/* otherwise, set it in the validation procedure */
-	storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);
-	if ((++validnum & 0xFFFF) == 0)
-	    debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);
     }
     eventAdd("storeCleanup", storeCleanup, NULL, 0.0, 1);
 }
 
+/* meta data recreated from disk image in swap directory */
 void
-storeValidate(StoreEntry * e, STVLDCB * callback, void *callback_data, void *tag)
+storeRebuildComplete(struct _store_rebuild_data *dc)
 {
-    valid_ctrl_t *ctrlp;
-    char *path;
-    struct stat *sb;
-#if !USE_ASYNC_IO
-    int x;
-#endif
-    assert(!EBIT_TEST(e->flags, ENTRY_VALIDATED));
-    if (e->swap_file_number < 0) {
-	EBIT_CLR(e->flags, ENTRY_VALIDATED);
-	callback(callback_data, 0, 0);
-	return;
-    }
-    path = storeSwapFullPath(e->swap_file_number, NULL);
-    sb = xmalloc(sizeof(struct stat));
-    ctrlp = xmalloc(sizeof(valid_ctrl_t));
-    ctrlp->sb = sb;
-    ctrlp->e = e;
-    ctrlp->callback = callback;
-    ctrlp->callback_data = callback_data;
-#if USE_ASYNC_IO
-    aioStat(path, sb, storeValidateComplete, ctrlp, tag);
-#else
+    double dt;
+    counts.objcount += dc->objcount;
+    counts.expcount += dc->expcount;
+    counts.scancount += dc->scancount;
+    counts.clashcount += dc->clashcount;
+    counts.dupcount += dc->dupcount;
+    counts.cancelcount += dc->cancelcount;
+    counts.invalid += dc->invalid;
+    counts.badflags += dc->badflags;
+    counts.bad_log_op += dc->bad_log_op;
+    counts.zero_object_sz += dc->zero_object_sz;
     /*
-     * When evaluating the actual arguments in a function call, the order
-     * in which the arguments and the function expression are evaluated is
-     * not specified;
+     * When store_dirs_rebuilding == 1, it means we are done reading
+     * or scanning all cache_dirs.  Now report the stats and start
+     * the validation (storeCleanup()) thread.
      */
-    x = stat(path, sb);
-    storeValidateComplete(-1, ctrlp, x, errno);
-#endif
-    return;
-}
-
-static void
-storeValidateComplete(int fd, void *data, int retcode, int errcode)
-{
-    valid_ctrl_t *ctrlp = data;
-    struct stat *sb = ctrlp->sb;
-    StoreEntry *e = ctrlp->e;
-    char *path;
-
-    if (retcode == -2 && errcode == -2) {
-	xfree(sb);
-	xfree(ctrlp);
-	ctrlp->callback(ctrlp->callback_data, retcode, errcode);
+    if (store_dirs_rebuilding > 1)
 	return;
-    }
-    if (retcode < 0 && errcode == EWOULDBLOCK) {
-	path = storeSwapFullPath(e->swap_file_number, NULL);
-	retcode = stat(path, sb);
-    }
-    if (retcode < 0 || sb->st_size == 0 || sb->st_size != e->swap_file_sz) {
-	EBIT_CLR(e->flags, ENTRY_VALIDATED);
-    } else {
-	EBIT_SET(e->flags, ENTRY_VALIDATED);
-	storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);
-    }
-    errno = errcode;
-    ctrlp->callback(ctrlp->callback_data, retcode, errcode);
-    xfree(sb);
-    xfree(ctrlp);
-}
-
-/* meta data recreated from disk image in swap directory */
-static void
-storeRebuildComplete(void)
-{
-    time_t r;
-    time_t stop;
-    stop = squid_curtime;
-    r = stop - RebuildState.start;
-    debug(20, 1) ("Finished rebuilding storage disk.\n");
-    debug(20, 1) ("  %7d Entries read from previous logfile.\n",
-	RebuildState.linecount);
-    debug(20, 1) ("  %7d Entries scanned from swap files.\n",
-	RebuildState.statcount);
-    debug(20, 1) ("  %7d Invalid entries.\n", RebuildState.invalid);
-    debug(20, 1) ("  %7d With invalid flags.\n", RebuildState.badflags);
-    debug(20, 1) ("  %7d Objects loaded.\n", RebuildState.objcount);
-    debug(20, 1) ("  %7d Objects expired.\n", RebuildState.expcount);
-    debug(20, 1) ("  %7d Objects cancelled.\n", RebuildState.cancelcount);
-    debug(20, 1) ("  %7d Duplicate URLs purged.\n", RebuildState.dupcount);
-    debug(20, 1) ("  %7d Swapfile clashes avoided.\n", RebuildState.clashcount);
-    debug(20, 1) ("  Took %d seconds (%6.1f objects/sec).\n",
-	r > 0 ? (int) r : 0,
-	(double) RebuildState.objcount / (r > 0 ? r : 1));
+    dt = tvSubDsec(rebuild_start, current_time);
+    debug(20, 1) ("Finished rebuilding storage from disk.\n");
+    debug(20, 1) ("  %7d Entries scanned\n", counts.scancount);
+    debug(20, 1) ("  %7d Invalid entries.\n", counts.invalid);
+    debug(20, 1) ("  %7d With invalid flags.\n", counts.badflags);
+    debug(20, 1) ("  %7d Objects loaded.\n", counts.objcount);
+    debug(20, 1) ("  %7d Objects expired.\n", counts.expcount);
+    debug(20, 1) ("  %7d Objects cancelled.\n", counts.cancelcount);
+    debug(20, 1) ("  %7d Duplicate URLs purged.\n", counts.dupcount);
+    debug(20, 1) ("  %7d Swapfile clashes avoided.\n", counts.clashcount);
+    debug(20, 1) ("  Took %3.1f seconds (%6.1f objects/sec).\n", dt,
+	(double) counts.objcount / (dt > 0.0 ? dt : 1.0));
     debug(20, 1) ("Beginning Validation Procedure\n");
     eventAdd("storeCleanup", storeCleanup, NULL, 0.0, 1);
 }
 
+/*
+ * this is ugly.  We don't actually start any rebuild threads here,
+ * but only initialize counters, etc.  The rebuild threads are
+ * actually started by the filesystem "fooDirInit" function.
+ */
 void
 storeRebuildStart(void)
 {
-    rebuild_dir *d;
-    int clean = 0;
-    int zero = 0;
-    FILE *fp;
-    int i;
-    memset(&RebuildState, '\0', sizeof(RebuildState));
-    RebuildState.start = squid_curtime;
-    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
-	d = xcalloc(1, sizeof(rebuild_dir));
-	d->dirn = i;
-	d->speed = opt_foreground_rebuild ? 1 << 30 : 50;
-	/*
-	 * If the swap.state file exists in the cache_dir, then
-	 * we'll use storeRebuildFromSwapLog(), otherwise we'll
-	 * use storeRebuildFromDirectory() to open up each file
-	 * and suck in the meta data.
-	 */
-	fp = storeDirOpenTmpSwapLog(i, &clean, &zero);
-	if (fp == NULL || zero) {
-	    if (fp != NULL)
-		fclose(fp);
-	    d->rebuild_func = storeRebuildFromDirectory;
-	} else {
-	    d->rebuild_func = storeRebuildFromSwapLog;
-	    d->log = fp;
-	    d->clean = clean;
-	}
-	d->next = RebuildState.rebuild_dir;
-	RebuildState.rebuild_dir = d;
-	if (!clean)
-	    RebuildState.need_to_validate = 1;
-	debug(20, 1) ("Rebuilding storage in Cache Dir #%d (%s)\n",
-	    i, clean ? "CLEAN" : "DIRTY");
-    }
-    eventAdd("storeRebuild", storeRebuildADirectory, NULL, 0.0, 1);
+    memset(&counts, '\0', sizeof(counts));
+    rebuild_start = current_time;
+    /*
+     * Note: store_dirs_rebuilding is initialized to 1 in globals.c.
+     * This prevents us from trying to write clean logs until we
+     * finished rebuilding for sure.  The corresponding decrement
+     * occurs in storeCleanup(), when it is finished.
+     */
 }
Index: squid/src/store_swapin.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_swapin.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_swapin.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_swapin.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapin.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_swapin.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Swapin Functions
  * AUTHOR: Duane Wessels
@@ -35,110 +35,50 @@
 
 #include "squid.h"
 
-typedef struct swapin_ctrl_t {
-    StoreEntry *e;
-    char *path;
-    SIH *callback;
-    void *callback_data;
-    store_client *sc;
-} swapin_ctrl_t;
+static STIOCB storeSwapInFileClosed;
 
-/* start swapping in */
-/* callback_data will become the tag on which the stat/open can be aborted */
 void
-storeSwapInStart(StoreEntry * e, SIH * callback, void *callback_data)
+storeSwapInStart(store_client * sc)
 {
-    swapin_ctrl_t *ctrlp;
+    StoreEntry *e = sc->entry;
     assert(e->mem_status == NOT_IN_MEMORY);
     if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) {
 	/* We're still reloading and haven't validated this entry yet */
-	callback(-1, callback_data);
 	return;
     }
     debug(20, 3) ("storeSwapInStart: called for %08X %s \n",
 	e->swap_file_number, storeKeyText(e->key));
-    assert(e->swap_status == SWAPOUT_WRITING || e->swap_status == SWAPOUT_DONE);
-    assert(e->swap_file_number >= 0);
-    assert(e->mem_obj != NULL);
-    ctrlp = xmalloc(sizeof(swapin_ctrl_t));
-    ctrlp->e = e;
-    ctrlp->callback = callback;
-    ctrlp->callback_data = callback_data;
-    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
-	storeSwapInValidateComplete(ctrlp, 0, 0);
-    else
-	storeValidate(e, storeSwapInValidateComplete, ctrlp, callback_data);
-}
-
-void
-storeSwapInValidateComplete(void *data, int retcode, int errcode)
-{
-    swapin_ctrl_t *ctrlp = (swapin_ctrl_t *) data;
-    StoreEntry *e;
-    if (retcode == -2 && errcode == -2) {
-	xfree(ctrlp);
+    if (e->swap_status != SWAPOUT_WRITING && e->swap_status != SWAPOUT_DONE) {
+	debug(20, 1) ("storeSwapInStart: bad swap_status (%s)\n",
+	    swapStatusStr[e->swap_status]);
 	return;
     }
-    e = ctrlp->e;
-    assert(e->mem_status == NOT_IN_MEMORY);
-    if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) {
-	/* Invoke a store abort that should free the memory object */
-	(ctrlp->callback) (-1, ctrlp->callback_data);
-	xfree(ctrlp);
+    if (e->swap_file_number < 0) {
+	debug(20, 1) ("storeSwapInStart: swap_file_number < 0\n");
 	return;
     }
-    ctrlp->path = xstrdup(storeSwapFullPath(e->swap_file_number, NULL));
-    debug(20, 3) ("storeSwapInValidateComplete: Opening %s\n", ctrlp->path);
-    store_open_disk_fd++;
-    file_open(ctrlp->path,
+    assert(e->mem_obj != NULL);
+    debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n",
+	e->swap_file_number);
+    sc->swapin_sio = storeOpen(e->swap_file_number,
 	O_RDONLY,
-	storeSwapInFileOpened,
-	ctrlp,
-	ctrlp->callback_data);
+	storeSwapInFileClosed,
+	sc);
+    cbdataLock(sc->swapin_sio);
 }
 
-void
-storeSwapInFileOpened(void *data, int fd, int errcode)
+static void
+storeSwapInFileClosed(void *data, int errflag, storeIOState * sio)
 {
-    swapin_ctrl_t *ctrlp = data;
-    StoreEntry *e = ctrlp->e;
-    MemObject *mem = e->mem_obj;
-    struct stat sb;
-    if (fd == -2 && errcode == -2) {
-	xfree(ctrlp->path);
-	xfree(ctrlp);
-	store_open_disk_fd--;
-	return;
-    }
-    assert(mem != NULL);
-    assert(e->mem_status == NOT_IN_MEMORY);
-    assert(e->swap_status == SWAPOUT_WRITING || e->swap_status == SWAPOUT_DONE);
-    if (fd < 0) {
-	debug(20, 3) ("storeSwapInFileOpened: Failed\n"
-	    "\tFile:\t'%s'\n\t URL:\t'%s'\n",
-	    ctrlp->path, storeUrl(e));
-	storeEntryDump(e, 3);
-	store_open_disk_fd--;
-    } else if (e->swap_status != SWAPOUT_DONE) {
-	(void) 0;
-    } else if (fstat(fd, &sb) < 0) {
-	debug(20, 1) ("storeSwapInFileOpened: fstat() FD %d: %s\n", fd, xstrerror());
-	file_close(fd);
-	store_open_disk_fd--;
-	fd = -1;
-    } else if (sb.st_size == 0 || sb.st_size != e->swap_file_sz) {
-	debug(20, 1) ("storeSwapInFileOpened: %s: Size mismatch: %d(fstat) != %d(object)\n", ctrlp->path, (int) sb.st_size, e->swap_file_sz);
-	file_close(fd);
-	store_open_disk_fd--;
-	fd = -1;
-    }
-    if (fd < 0) {
-	storeReleaseRequest(e);
-    } else {
-	debug(20, 5) ("storeSwapInFileOpened: initialized '%s' for '%s'\n",
-	    ctrlp->path, storeUrl(e));
+    store_client *sc = data;
+    STCB *callback;
+    debug(20, 3) ("storeSwapInFileClosed: sio=%p, errflag=%d\n",
+	sio, errflag);
+    cbdataUnlock(sio);
+    sc->swapin_sio = NULL;
+    if ((callback = sc->callback)) {
+	assert(errflag <= 0);
+	sc->callback = NULL;
+	callback(sc->callback_data, sc->copy_buf, errflag);
     }
-    (ctrlp->callback) (fd, ctrlp->callback_data);
-    xfree(ctrlp->path);
-    xfree(ctrlp);
 }
Index: squid/src/store_swapmeta.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_swapmeta.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
diff -u -r1.1.1.1 -r1.1.1.2
--- squid/src/store_swapmeta.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/src/store_swapmeta.c	26 Jan 2000 03:25:01 -0000	1.1.1.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapmeta.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $
+ * $Id: store_swapmeta.c,v 1.1.1.2 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Swapfile Metadata
  * AUTHOR: Kostas Anagnostakis
@@ -126,7 +126,15 @@
     assert(buflen > (sizeof(char) + sizeof(int)));
     while (buflen - j > (sizeof(char) + sizeof(int))) {
 	type = buf[j++];
+	if (type < STORE_META_VOID || type > STORE_META_END) {
+	    debug(20, 0) ("storeSwapMetaUnpack: bad type (%d)!\n", type);
+	    break;
+	}
 	xmemcpy(&length, &buf[j], sizeof(int));
+	if (length < 0 || length > (1 << 10)) {
+	    debug(20, 0) ("storeSwapMetaUnpack: insane length (%d)!\n", length);
+	    break;
+	}
 	j += sizeof(int);
 	if (j + length > buflen) {
 	    debug(20, 0) ("storeSwapMetaUnpack: overflow!\n");
Index: squid/src/store_swapout.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_swapout.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/store_swapout.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_swapout.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapout.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: store_swapout.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Swapout Functions
  * AUTHOR: Duane Wessels
@@ -35,176 +35,116 @@
 
 #include "squid.h"
 
-typedef struct swapout_ctrl_t {
-    char *swapfilename;
-    int oldswapstatus;
-    StoreEntry *e;
-} swapout_ctrl_t;
-
-static FOCB storeSwapOutFileOpened;
 static off_t storeSwapOutObjectBytesOnDisk(const MemObject *);
 static void storeSwapOutStart(StoreEntry * e);
-static DWCB storeSwapOutHandle;
+static STIOCB storeSwapOutFileClosed;
 
 /* start swapping object to disk */
 static void
 storeSwapOutStart(StoreEntry * e)
 {
-    swapout_ctrl_t *ctrlp = xmalloc(sizeof(swapout_ctrl_t));
-    assert(e->mem_obj);
-    cbdataAdd(ctrlp, cbdataXfree, 0);
+    generic_cbdata *c;
+    MemObject *mem = e->mem_obj;
+    int swap_hdr_sz = 0;
+    tlv *tlv_list;
+    char *buf;
+    assert(mem);
     storeLockObject(e);
     e->swap_file_number = storeDirMapAllocate();
-    ctrlp->swapfilename = xstrdup(storeSwapFullPath(e->swap_file_number, NULL));
-    ctrlp->e = e;
-    ctrlp->oldswapstatus = e->swap_status;
-    e->swap_status = SWAPOUT_OPENING;
-    e->mem_obj->swapout.ctrl = ctrlp;
-    store_open_disk_fd++;
-    file_open(ctrlp->swapfilename,
-	O_WRONLY | O_CREAT | O_TRUNC,
-	storeSwapOutFileOpened,
-	ctrlp,
-	e);
-}
-
-static void
-storeSwapOutHandle(int fdnotused, int flag, size_t len, void *data)
-{
-    swapout_ctrl_t *ctrlp = data;
-    StoreEntry *e = ctrlp->e;
-    MemObject *mem = e->mem_obj;
-    debug(20, 3) ("storeSwapOutHandle: '%s', len=%d\n", storeKeyText(e->key), (int) len);
-    if (flag < 0) {
-	debug(20, 1) ("storeSwapOutHandle: SwapOut failure (err code = %d).\n",
-	    flag);
+    c = xcalloc(1, sizeof(*c));
+    c->data = e;
+    cbdataAdd(c, cbdataXfree, 0);
+    mem->swapout.sio = storeOpen(e->swap_file_number,
+	O_WRONLY, storeSwapOutFileClosed, c);
+    if (NULL == mem->swapout.sio) {
 	e->swap_status = SWAPOUT_NONE;
-	if (e->swap_file_number > -1) {
-	    storeUnlinkFileno(e->swap_file_number);
-	    storeDirMapBitReset(e->swap_file_number);
-	    if (flag == DISK_NO_SPACE_LEFT) {
-		storeDirDiskFull(e->swap_file_number);
-		storeDirConfigure();
-		storeConfigure();
-	    }
-	    e->swap_file_number = -1;
-	}
-	storeReleaseRequest(e);
-	storeSwapOutFileClose(e);
-	return;
-    }
-#if USE_ASYNC_IO
-    if (mem == NULL) {
-	debug(20, 1) ("storeSwapOutHandle: mem == NULL : Cancelling swapout\n");
-	return;
-    }
-#else
-    assert(mem != NULL);
-#endif
-    assert(mem->swap_hdr_sz != 0);
-    mem->swapout.done_offset += len;
-    if (e->store_status == STORE_PENDING) {
-	storeCheckSwapOut(e);
-	return;
-    } else if (mem->swapout.done_offset < objectLen(e) + mem->swap_hdr_sz) {
-	storeCheckSwapOut(e);
+	storeDirMapBitReset(e->swap_file_number);
+	e->swap_file_number = -1;
+	cbdataFree(c);
+	storeUnlockObject(e);
 	return;
     }
-    /* swapping complete */
-    debug(20, 5) ("storeSwapOutHandle: SwapOut complete: '%s' to %s.\n",
-	storeUrl(e), storeSwapFullPath(e->swap_file_number, NULL));
-    e->swap_file_sz = objectLen(e) + mem->swap_hdr_sz;
-    e->swap_status = SWAPOUT_DONE;
-    storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);
-    if (storeCheckCachable(e)) {
-	storeLog(STORE_LOG_SWAPOUT, e);
-	storeDirSwapLog(e, SWAP_LOG_ADD);
-    }
-    /* Note, we don't otherwise call storeReleaseRequest() here because
-     * storeCheckCachable() does it for is if necessary */
-    storeSwapOutFileClose(e);
+    e->swap_status = SWAPOUT_WRITING;
+    cbdataLock(mem->swapout.sio);
+    debug(20, 5) ("storeSwapOutStart: Begin SwapOut '%s' to fileno %08X\n",
+	storeUrl(e), e->swap_file_number);
+    tlv_list = storeSwapMetaBuild(e);
+    buf = storeSwapMetaPack(tlv_list, &swap_hdr_sz);
+    storeSwapTLVFree(tlv_list);
+    mem->swap_hdr_sz = (size_t) swap_hdr_sz;
+    storeWrite(mem->swapout.sio, buf, mem->swap_hdr_sz, 0, xfree);
 }
 
 void
-storeCheckSwapOut(StoreEntry * e)
+storeSwapOut(StoreEntry * e)
 {
     MemObject *mem = e->mem_obj;
     off_t lowest_offset;
     off_t new_mem_lo;
-    off_t on_disk;
+    off_t on_disk = 0;
     size_t swapout_size;
     char *swap_buf;
     ssize_t swap_buf_len;
-    int hdr_len = 0;
     if (mem == NULL)
 	return;
     /* should we swap something out to disk? */
-    debug(20, 7) ("storeCheckSwapOut: %s\n", storeUrl(e));
-    debug(20, 7) ("storeCheckSwapOut: store_status = %s\n",
+    debug(20, 7) ("storeSwapOut: %s\n", storeUrl(e));
+    debug(20, 7) ("storeSwapOut: store_status = %s\n",
 	storeStatusStr[e->store_status]);
     if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {
 	assert(EBIT_TEST(e->flags, RELEASE_REQUEST));
 	storeSwapOutFileClose(e);
 	return;
     }
-    debug(20, 7) ("storeCheckSwapOut: mem->inmem_lo = %d\n",
+    debug(20, 7) ("storeSwapOut: mem->inmem_lo = %d\n",
 	(int) mem->inmem_lo);
-    debug(20, 7) ("storeCheckSwapOut: mem->inmem_hi = %d\n",
+    debug(20, 7) ("storeSwapOut: mem->inmem_hi = %d\n",
 	(int) mem->inmem_hi);
-    debug(20, 7) ("storeCheckSwapOut: swapout.queue_offset = %d\n",
+    debug(20, 7) ("storeSwapOut: swapout.queue_offset = %d\n",
 	(int) mem->swapout.queue_offset);
-    debug(20, 7) ("storeCheckSwapOut: swapout.done_offset = %d\n",
-	(int) mem->swapout.done_offset);
-#if USE_ASYNC_IO
-    if (mem->inmem_hi < mem->swapout.queue_offset) {
-	storeAbort(e);
-	assert(EBIT_TEST(e->flags, RELEASE_REQUEST));
-	storeSwapOutFileClose(e);
-	return;
-    }
-#else
+    if (mem->swapout.sio)
+	debug(20, 7) ("storeSwapOut: storeOffset() = %d\n",
+	    (int) storeOffset(mem->swapout.sio));
     assert(mem->inmem_hi >= mem->swapout.queue_offset);
-#endif
     lowest_offset = storeLowestMemReaderOffset(e);
-    debug(20, 7) ("storeCheckSwapOut: lowest_offset = %d\n",
+    debug(20, 7) ("storeSwapOut: lowest_offset = %d\n",
 	(int) lowest_offset);
     new_mem_lo = lowest_offset;
     assert(new_mem_lo >= mem->inmem_lo);
-    /*
-     * We should only free up to what we know has been written to
-     * disk, not what has been queued for writing.  Otherwise there
-     * will be a chunk of the data which is not in memory and is
-     * not yet on disk.
-     */
-    if (storeSwapOutAble(e))
+    if (storeSwapOutAble(e)) {
+	/*
+	 * We should only free up to what we know has been written
+	 * to disk, not what has been queued for writing.  Otherwise
+	 * there will be a chunk of the data which is not in memory
+	 * and is not yet on disk.
+	 */
 	if ((on_disk = storeSwapOutObjectBytesOnDisk(mem)) < new_mem_lo)
 	    new_mem_lo = on_disk;
+    } else {
+	/*
+	 * Its not swap-able, so we must make it PRIVATE.  Even if
+	 * be only one MEM client and all others must read from
+	 * disk.
+	 */
+	storeReleaseRequest(e);
+    }
     stmemFreeDataUpto(&mem->data_hdr, new_mem_lo);
     mem->inmem_lo = new_mem_lo;
     if (e->swap_status == SWAPOUT_WRITING)
-	assert(mem->inmem_lo <= mem->swapout.done_offset);
+	assert(mem->inmem_lo <= on_disk);
     if (!storeSwapOutAble(e))
 	return;
     swapout_size = (size_t) (mem->inmem_hi - mem->swapout.queue_offset);
-    debug(20, 7) ("storeCheckSwapOut: swapout_size = %d\n",
+    debug(20, 7) ("storeSwapOut: swapout_size = %d\n",
 	(int) swapout_size);
     if (swapout_size == 0) {
-	if (e->store_status == STORE_OK && !storeSwapOutWriteQueued(mem)) {
-	    debug(20, 7) ("storeCheckSwapOut: nothing to write for STORE_OK\n");
-	    if (e->swap_file_number > -1) {
-		storeUnlinkFileno(e->swap_file_number);
-		storeDirMapBitReset(e->swap_file_number);
-		e->swap_file_number = -1;
-	    }
-	    e->swap_status = SWAPOUT_NONE;
-	    storeReleaseRequest(e);
+	if (e->store_status == STORE_OK)
 	    storeSwapOutFileClose(e);
-	}
-	return;
+	return;			/* Nevermore! */
     }
     if (e->store_status == STORE_PENDING) {
 	/* wait for a full block to write */
-	if (swapout_size < VM_WINDOW_SZ)
+	if (swapout_size < DISK_PAGE_SIZE)
 	    return;
 	/*
 	 * Wait until we are below the disk FD limit, only if the
@@ -213,149 +153,120 @@
 	if (storeTooManyDiskFilesOpen() && !fwdCheckDeferRead(-1, e))
 	    return;
     }
-    /* Ok, we have stuff to swap out.  Is there a swapout.fd open? */
+    /* Ok, we have stuff to swap out.  Is there a swapout.sio open? */
     if (e->swap_status == SWAPOUT_NONE) {
-	assert(mem->swapout.fd == -1);
+	assert(mem->swapout.sio == NULL);
 	assert(mem->inmem_lo == 0);
 	if (storeCheckCachable(e))
 	    storeSwapOutStart(e);
-	/* else ENTRY_CACHABLE will be cleared and we'll never get
-	 * here again */
-	return;
+	else
+	    return;
+	/* ENTRY_CACHABLE will be cleared and we'll never get here again */
     }
-    if (e->swap_status == SWAPOUT_OPENING)
+    if (NULL == mem->swapout.sio)
 	return;
-    assert(mem->swapout.fd > -1);
-    if (swapout_size > STORE_SWAP_BUF)
-	swapout_size = STORE_SWAP_BUF;
-    swap_buf = memAllocate(MEM_DISK_BUF);
-    swap_buf_len = stmemCopy(&mem->data_hdr,
-	mem->swapout.queue_offset,
-	swap_buf,
-	swapout_size);
-    if (swap_buf_len < 0) {
-	debug(20, 1) ("stmemCopy returned %d for '%s'\n", swap_buf_len, storeKeyText(e->key));
-	storeUnlinkFileno(e->swap_file_number);
-	storeDirMapBitReset(e->swap_file_number);
-	e->swap_file_number = -1;
-	e->swap_status = SWAPOUT_NONE;
-	memFree(swap_buf, MEM_DISK_BUF);
-	storeReleaseRequest(e);
-	storeSwapOutFileClose(e);
+    do {
+	if (swapout_size > DISK_PAGE_SIZE)
+	    swapout_size = DISK_PAGE_SIZE;
+	swap_buf = memAllocate(MEM_DISK_BUF);
+	swap_buf_len = stmemCopy(&mem->data_hdr,
+	    mem->swapout.queue_offset,
+	    swap_buf,
+	    swapout_size);
+	if (swap_buf_len < 0) {
+	    debug(20, 1) ("stmemCopy returned %d for '%s'\n", swap_buf_len, storeKeyText(e->key));
+	    storeUnlink(e->swap_file_number);
+	    storeDirMapBitReset(e->swap_file_number);
+	    e->swap_file_number = -1;
+	    e->swap_status = SWAPOUT_NONE;
+	    memFree(swap_buf, MEM_DISK_BUF);
+	    storeReleaseRequest(e);
+	    storeSwapOutFileClose(e);
+	    return;
+	}
+	debug(20, 3) ("storeSwapOut: swap_buf_len = %d\n", (int) swap_buf_len);
+	assert(swap_buf_len > 0);
+	debug(20, 3) ("storeSwapOut: swapping out %d bytes from %d\n",
+	    swap_buf_len, (int) mem->swapout.queue_offset);
+	mem->swapout.queue_offset += swap_buf_len;
+	storeWrite(mem->swapout.sio, swap_buf, swap_buf_len, -1, memFreeDISK);
+	/* the storeWrite() call might generate an error */
+	if (e->swap_status != SWAPOUT_WRITING)
+	    break;
+	swapout_size = (size_t) (mem->inmem_hi - mem->swapout.queue_offset);
+	if (e->store_status == STORE_PENDING)
+	    if (swapout_size < DISK_PAGE_SIZE)
+		break;
+    } while (swapout_size > 0);
+    if (NULL == mem->swapout.sio)
+	/* oops, we're not swapping out any more */
 	return;
+    if (e->store_status == STORE_OK) {
+	/*
+	 * If the state is STORE_OK, then all data must have been given
+	 * to the filesystem at this point because storeSwapOut() is
+	 * not going to be called again for this entry.
+	 */
+	assert(mem->inmem_hi == mem->swapout.queue_offset);
+	storeSwapOutFileClose(e);
     }
-    debug(20, 3) ("storeCheckSwapOut: swap_buf_len = %d\n", (int) swap_buf_len);
-    assert(swap_buf_len > 0);
-    debug(20, 3) ("storeCheckSwapOut: swapping out %d bytes from %d\n",
-	swap_buf_len, (int) mem->swapout.queue_offset);
-    mem->swapout.queue_offset += swap_buf_len - hdr_len;
-    file_write(mem->swapout.fd,
-	-1,
-	swap_buf,
-	swap_buf_len,
-	storeSwapOutHandle,
-	mem->swapout.ctrl,
-	memFreeDISK);
 }
 
 void
 storeSwapOutFileClose(StoreEntry * e)
 {
     MemObject *mem = e->mem_obj;
-    swapout_ctrl_t *ctrlp;
     assert(mem != NULL);
     debug(20, 3) ("storeSwapOutFileClose: %s\n", storeKeyText(e->key));
-    if (mem->swapout.fd < 0) {
-#if USE_ASYNC_IO
-	aioCancel(-1, e);	/* Make doubly certain pending ops are gone */
-#endif
+    debug(20, 3) ("storeSwapOutFileClose: sio = %p\n", mem->swapout.sio);
+    if (mem->swapout.sio == NULL)
 	return;
-    }
-    ctrlp = mem->swapout.ctrl;
-    file_close(mem->swapout.fd);
-    store_open_disk_fd--;
-    mem->swapout.fd = -1;
-    xfree(ctrlp->swapfilename);
-    cbdataFree(ctrlp);
-    mem->swapout.ctrl = NULL;
-    storeUnlockObject(e);
+    storeClose(mem->swapout.sio);
 }
 
 static void
-storeSwapOutFileOpened(void *data, int fd, int errcode)
+storeSwapOutFileClosed(void *data, int errflag, storeIOState * sio)
 {
-    swapout_ctrl_t *ctrlp = data;
-    StoreEntry *e = ctrlp->e;
+    generic_cbdata *c = data;
+    StoreEntry *e = c->data;
     MemObject *mem = e->mem_obj;
-    int swap_hdr_sz = 0;
-    tlv *tlv_list;
-    char *buf;
-    if (fd == -2 && errcode == -2) {	/* Cancelled - Clean up */
-	xfree(ctrlp->swapfilename);
-	cbdataFree(ctrlp);
-	mem->swapout.ctrl = NULL;
-	store_open_disk_fd--;
-	return;
-    }
-    assert(e->swap_status == SWAPOUT_OPENING);
-    if (fd < 0) {
-	debug(20, 0) ("storeSwapOutFileOpened: Unable to open swapfile: %s\n\t%s\n",
-	    ctrlp->swapfilename, xstrerror());
+    assert(e->swap_status == SWAPOUT_WRITING);
+    cbdataFree(c);
+    if (errflag) {
+	debug(20, 1) ("storeSwapOutFileClosed: swapfile %08X, errflag=%d\n\t%s\n",
+	    e->swap_file_number, errflag, xstrerror());
 	/*
 	 * yuck.  don't clear the filemap bit for some errors so that
 	 * we don't try re-using it over and over
 	 */
 	if (errno != EPERM)
 	    storeDirMapBitReset(e->swap_file_number);
+	if (errflag == DISK_NO_SPACE_LEFT) {
+	    storeDirDiskFull(e->swap_file_number);
+	    storeDirConfigure();
+	    storeConfigure();
+	}
+	storeReleaseRequest(e);
 	e->swap_file_number = -1;
-	e->swap_status = ctrlp->oldswapstatus;
-	xfree(ctrlp->swapfilename);
-	cbdataFree(ctrlp);
-	mem->swapout.ctrl = NULL;
-	store_open_disk_fd--;
-	return;
+	e->swap_status = SWAPOUT_NONE;
+    } else {
+	/* swapping complete */
+	debug(20, 3) ("storeSwapOutFileClosed: SwapOut complete: '%s' to %08X\n",
+	    storeUrl(e), e->swap_file_number);
+	e->swap_file_sz = objectLen(e) + mem->swap_hdr_sz;
+	e->swap_status = SWAPOUT_DONE;
+	storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);
+	if (storeCheckCachable(e)) {
+	    storeLog(STORE_LOG_SWAPOUT, e);
+	    storeDirSwapLog(e, SWAP_LOG_ADD);
+	}
     }
-    mem->swapout.fd = (short) fd;
-    e->swap_status = SWAPOUT_WRITING;
-    debug(20, 5) ("storeSwapOutFileOpened: Begin SwapOut '%s' to FD %d '%s'\n",
-	storeUrl(e), fd, ctrlp->swapfilename);
-    debug(20, 5) ("swap_file_number=%08X\n", e->swap_file_number);
-    tlv_list = storeSwapMetaBuild(e);
-    buf = storeSwapMetaPack(tlv_list, &swap_hdr_sz);
-    storeSwapTLVFree(tlv_list);
-    mem->swap_hdr_sz = (size_t) swap_hdr_sz;
-    file_write(mem->swapout.fd,
-	-1,
-	buf,
-	mem->swap_hdr_sz,
-	storeSwapOutHandle,
-	ctrlp,
-	xfree);
-}
-
-/*
- * Return 1 if we have some data queued.  If there is no data queued,
- * then 'done_offset' equals 'queued_offset' + 'swap_hdr_sz'
- *
- * done_offset represents data written to disk (including the swap meta
- * header), but queued_offset is relative to the in-memory data, and
- * does not include the meta header.
- */
-int
-storeSwapOutWriteQueued(MemObject * mem)
-{
-    /*
-     * this function doesn't get called much, so I'm using
-     * local variables to improve readability.  pphhbbht.
-     */
-    off_t queued = mem->swapout.queue_offset;
-    off_t done = mem->swapout.done_offset;
-    size_t hdr = mem->swap_hdr_sz;
-    assert(queued + hdr >= done);
-    return (queued + hdr > done);
+    debug(20, 3) ("storeSwapOutFileClosed: %s:%d\n", __FILE__, __LINE__);
+    mem->swapout.sio = NULL;
+    cbdataUnlock(sio);
+    storeUnlockObject(e);
 }
 
-
 /*
  * How much of the object data is on the disk?
  */
@@ -363,7 +274,7 @@
 storeSwapOutObjectBytesOnDisk(const MemObject * mem)
 {
     /*
-     * NOTE: done_offset represents the disk file size,
+     * NOTE: storeOffset() represents the disk file size,
      * not the amount of object data on disk.
      * 
      * If we don't have at least 'swap_hdr_sz' bytes
@@ -373,9 +284,13 @@
      * meaning we haven't even opened the swapout file
      * yet.
      */
-    if (mem->swapout.done_offset <= mem->swap_hdr_sz)
+    off_t nwritten;
+    if (mem->swapout.sio == NULL)
 	return 0;
-    return mem->swapout.done_offset - mem->swap_hdr_sz;
+    nwritten = storeOffset(mem->swapout.sio);
+    if (nwritten <= mem->swap_hdr_sz)
+	return 0;
+    return nwritten - mem->swap_hdr_sz;
 }
 
 /*
@@ -385,13 +300,10 @@
 storeSwapOutAble(const StoreEntry * e)
 {
     store_client *sc;
-    if (e->swap_status == SWAPOUT_OPENING)
-	return 1;
-    if (e->mem_obj->swapout.fd > -1)
+    if (e->mem_obj->swapout.sio != NULL)
 	return 1;
     if (e->mem_obj->inmem_lo > 0)
 	return 0;
-    /* swapout.fd == -1 && inmem_lo == 0 */
     /*
      * If there are DISK clients, we must write to disk
      * even if its not cachable
@@ -399,5 +311,8 @@
     for (sc = e->mem_obj->clients; sc; sc = sc->next)
 	if (sc->type == STORE_DISK_CLIENT)
 	    return 1;
+    if (store_dirs_rebuilding)
+	if (!EBIT_TEST(e->flags, ENTRY_SPECIAL))
+	    return 0;
     return EBIT_TEST(e->flags, ENTRY_CACHABLE);
 }
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/structs.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/structs.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: structs.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -75,6 +75,8 @@
     char *passwd;
     int passwd_ok;		/* 1 = passwd checked OK */
     long expiretime;
+    struct in_addr ipaddr;	/* IP addr this user authenticated from */
+    time_t ip_expiretime;
 };
 
 struct _acl_deny_info_list {
@@ -142,12 +144,12 @@
     struct in_addr src_addr;
     struct in_addr dst_addr;
     struct in_addr my_addr;
+    unsigned short my_port;
     request_t *request;
 #if USE_IDENT
     ConnStateData *conn;	/* hack for ident */
     char ident[USER_IDENT_SZ];
 #endif
-    char browser[BROWSERNAMELEN];
     acl_proxy_auth_user *auth_user;
     acl_lookup_state state[ACL_ENUM_MAX];
 #if SQUID_SNMP
@@ -189,6 +191,11 @@
     relist *next;
 };
 
+struct _sockaddr_in_list {
+    struct sockaddr_in s;
+    sockaddr_in_list *next;
+};
+
 #if DELAY_POOLS
 struct _delaySpec {
     int restore_bps;
@@ -231,6 +238,14 @@
 	int pct;
 	size_t max;
     } quickAbort;
+#if HEAP_REPLACEMENT
+    char *replPolicy;
+#else
+    /* 
+     * Note: the non-LRU policies do not use referenceAge, but we cannot
+     * remove it until we find out how to implement #else for cf_parser.c
+     */
+#endif
     time_t referenceAge;
     time_t negativeTtl;
     time_t negativeDnsTtl;
@@ -240,19 +255,22 @@
 	time_t read;
 	time_t lifetime;
 	time_t connect;
+	time_t peer_connect;
 	time_t request;
 	time_t pconn;
 	time_t siteSelect;
 	time_t deadPeer;
 	int icp_query;		/* msec */
+	int icp_query_max;	/* msec */
 	int mcast_icp_query;	/* msec */
 #if USE_IDENT
 	time_t ident;
 #endif
     } Timeout;
-    size_t maxRequestSize;
+    size_t maxRequestHeaderSize;
+    size_t maxRequestBodySize;
+    size_t maxReplyBodySize;
     struct {
-	ushortlist *http;
 	u_short icp;
 #if USE_HTCP
 	u_short htcp;
@@ -261,13 +279,22 @@
 	u_short snmp;
 #endif
     } Port;
+    struct {
+	sockaddr_in_list *http;
+    } Sockaddr;
 #if SQUID_SNMP
     struct {
 	char *configFile;
 	char *agentInfo;
-	u_short localPort;
     } Snmp;
 #endif
+#if USE_WCCP
+    struct {
+	struct in_addr router;
+	struct in_addr incoming;
+	struct in_addr outgoing;
+    } Wccp;
+#endif
     char *as_whois_server;
     struct {
 	char *log;
@@ -282,7 +309,7 @@
     char *effectiveGroup;
     struct {
 	char *dnsserver;
-	char *redirect;
+	wordlist *redirect;
 	wordlist *authenticate;
 	char *pinger;
 	char *unlinkd;
@@ -291,6 +318,7 @@
     int redirectChildren;
     int authenticateChildren;
     int authenticateTTL;
+    int authenticateIpTTL;
     struct {
 	char *host;
 	u_short port;
@@ -302,6 +330,7 @@
     char *mimeTablePathname;
     char *visibleHostname;
     char *uniqueHostname;
+    wordlist *hostnameAliases;
     char *errHtmlText;
     struct {
 	char *host;
@@ -310,7 +339,6 @@
 	u_short port;
     } Announce;
     struct {
-	struct in_addr tcp_incoming;
 	struct in_addr tcp_outgoing;
 	struct in_addr udp_incoming;
 	struct in_addr udp_outgoing;
@@ -373,9 +401,13 @@
 #endif
 	int offline;
 	int redir_rewrites_host;
-	int persistent_client_posts;
 	int prefer_direct;
 	int strip_query_terms;
+	int redirector_bypass;
+	int ignore_unknown_nameservers;
+#if USE_CACHE_DIGESTS
+	int digest_generation;
+#endif
     } onoff;
     acl *aclList;
     struct {
@@ -393,6 +425,7 @@
 #if USE_IDENT
 	acl_access *identLookup;
 #endif
+	acl_access *redirector;
     } accessList;
     acl_deny_info_list *denyInfoList;
     char *proxyAuthRealm;
@@ -424,8 +457,10 @@
 #endif
     struct {
 	int icp_average;
+	int dns_average;
 	int http_average;
 	int icp_min_poll;
+	int dns_min_poll;
 	int http_min_poll;
     } comm_incoming;
     int max_open_disk_fds;
@@ -434,12 +469,23 @@
 #if MULTICAST_MISS_STREAM
     struct {
 	struct in_addr addr;
+	int ttl;
 	unsigned short port;
 	char *encode_key;
     } mcast_miss;
 #endif
     HttpHeaderMask anonymize_headers;
     char *coredump_dir;
+    char *chroot_dir;
+#if USE_CACHE_DIGESTS
+    struct {
+	int bits_per_entry;
+	time_t rebuild_period;
+	time_t rewrite_period;
+	size_t swapout_chunk_size;
+	int rebuild_chunk_percentage;
+    } digest;
+#endif
 };
 
 struct _SquidConfig2 {
@@ -518,9 +564,6 @@
 	unsigned int nonblocking:1;
 	unsigned int ipc:1;
 	unsigned int called_connect:1;
-#ifdef OPTIMISTIC_IO
-	unsigned int calling_io_handler:1;
-#endif
     } flags;
     int bytes_read;
     int bytes_written;
@@ -602,12 +645,13 @@
 struct _HttpHdrCc {
     int mask;
     int max_age;
+    int s_maxage;
 };
 
 /* http byte-range-spec */
 struct _HttpHdrRangeSpec {
-    size_t offset;
-    size_t length;
+    ssize_t offset;
+    ssize_t length;
 };
 
 /* There may be more than one byte range specified in the request.
@@ -621,7 +665,7 @@
 /* http content-range header field */
 struct _HttpHdrContRange {
     HttpHdrRangeSpec spec;
-    size_t elength;		/* entity length, not content length */
+    ssize_t elength;		/* entity length, not content length */
 };
 
 /* some fields can hold either time or etag specs (e.g. If-Range) */
@@ -635,8 +679,8 @@
 struct _HttpHdrRangeIter {
     HttpHdrRangePos pos;
     const HttpHdrRangeSpec *spec;	/* current spec at pos */
-    size_t debt_size;		/* bytes left to send from the current spec */
-    size_t prefix_size;		/* the size of the incoming HTTP msg prefix */
+    ssize_t debt_size;		/* bytes left to send from the current spec */
+    ssize_t prefix_size;	/* the size of the incoming HTTP msg prefix */
     String boundary;		/* boundary for multipart responses */
 };
 
@@ -1044,6 +1088,7 @@
     } mcast;
 #if USE_CACHE_DIGESTS
     PeerDigest *digest;
+    char *digest_url;
 #endif
     int tcp_up;			/* 0 if a connect() fails */
     time_t last_fail_time;
@@ -1060,6 +1105,7 @@
     } carp;
 #endif
     char *login;		/* Proxy authorization */
+    time_t connect_timeout;
 };
 
 struct _net_db_name {
@@ -1183,7 +1229,7 @@
     STCB *callback;
     void *callback_data;
     StoreEntry *entry;		/* ptr to the parent StoreEntry, argh! */
-    int swapin_fd;
+    storeIOState *swapin_sio;
     struct {
 	unsigned int disk_io_pending:1;
 	unsigned int store_copying:1;
@@ -1207,9 +1253,7 @@
     int nclients;
     struct {
 	off_t queue_offset;	/* relative to in-mem data */
-	off_t done_offset;	/* relative to swap file with meta headers! */
-	int fd;
-	void *ctrl;
+	storeIOState *sio;
     } swapout;
     HttpReply *reply;
     request_t *request;
@@ -1222,7 +1266,14 @@
 	void *data;
     } abort;
     char *log_url;
+#if HEAP_REPLACEMENT
+    /* 
+     * A MemObject knows where it is in the in-memory heap.
+     */
+    heap_node *node;
+#else
     dlink_node lru;
+#endif
     int id;
     ssize_t object_sz;
     size_t swap_hdr_sz;
@@ -1240,8 +1291,12 @@
     size_t swap_file_sz;
     u_short refcount;
     u_short flags;
-    int swap_file_number;
+    sfileno swap_file_number;
+#if HEAP_REPLACEMENT
+    heap_node *node;
+#else
     dlink_node lru;
+#endif
     u_short lock_count;		/* Assume < 65536! */
     mem_status_t mem_status:3;
     ping_status_t ping_status:3;
@@ -1250,18 +1305,43 @@
 };
 
 struct _SwapDir {
-    char *path;
-    int l1;
-    int l2;
+    swapdir_t type;
+    fileMap *map;
     int cur_size;
     int max_size;
+    char *path;
+    int index;			/* This entry's index into the swapDirs array */
     int suggest;
-    fileMap *map;
-    int swaplog_fd;
     struct {
 	unsigned int selected:1;
 	unsigned int read_only:1;
     } flags;
+    STINIT *init;
+    STNEWFS *newfs;
+    struct {
+	STOBJOPEN *open;
+	STOBJCLOSE *close;
+	STOBJREAD *read;
+	STOBJWRITE *write;
+	STOBJUNLINK *unlink;
+    } obj;
+    struct {
+	STLOGOPEN *open;
+	STLOGCLOSE *close;
+	STLOGWRITE *write;
+	struct {
+	    STLOGCLEANOPEN *open;
+	    STLOGCLEANWRITE *write;
+	    void *state;
+	} clean;
+    } log;
+    union {
+	struct {
+	    int l1;
+	    int l2;
+	    int swaplog_fd;
+	} ufs;
+    } u;
 };
 
 struct _request_flags {
@@ -1285,6 +1365,49 @@
     unsigned int internal:1;
 };
 
+struct _link_list {
+    void *ptr;
+    struct _link_list *next;
+};
+
+struct _storeIOState {
+    sfileno swap_file_number;
+    mode_t mode;
+    size_t st_size;		/* do stat(2) after read open */
+    off_t offset;		/* current offset pointer */
+    STIOCB *callback;
+    void *callback_data;
+    struct {
+	STRCB *callback;
+	void *callback_data;
+    } read;
+    struct {
+	unsigned int closing:1;	/* debugging aid */
+    } flags;
+    union {
+	struct {
+	    int fd;
+	    struct {
+		unsigned int close_request:1;
+		unsigned int reading:1;
+		unsigned int writing:1;
+	    } flags;
+	} ufs;
+	struct {
+	    int fd;
+	    struct {
+		unsigned int close_request:1;
+		unsigned int reading:1;
+		unsigned int writing:1;
+		unsigned int opening:1;
+	    } flags;
+	    const char *read_buf;
+	    link_list *pending_writes;
+	    link_list *pending_reads;
+	} aufs;
+    } type;
+};
+
 struct _request_t {
     method_t method;
     protocol_t protocol;
@@ -1302,14 +1425,18 @@
     time_t ims;
     int imslen;
     int max_forwards;
+    /* these in_addr's could probably be sockaddr_in's */
     struct in_addr client_addr;
     struct in_addr my_addr;
+    unsigned short my_port;
     HttpHeader header;
     char *body;
     size_t body_sz;
+    int content_length;
     HierarchyLogEntry hier;
     err_type err_type;
     char *peer_login;		/* Configured peer login:password */
+    time_t lastmod;		/* Used on refreshes */
 };
 
 struct _cachemgr_passwd {
@@ -1364,11 +1491,11 @@
 	unsigned int flag_cbdata:1;
     } flags;
     struct {
+	wordlist *server_msg;
 	char *request;
 	char *reply;
     } ftp;
     char *request_hdrs;
-    wordlist *ftp_server_msg;
 };
 
 /*
@@ -1462,6 +1589,7 @@
     double cputime;
     struct timeval timestamp;
     StatHist comm_icp_incoming;
+    StatHist comm_dns_incoming;
     StatHist comm_http_incoming;
     StatHist select_fds_hist;
     struct {
@@ -1519,7 +1647,7 @@
 
 struct _storeSwapLogData {
     char op;
-    int swap_file_number;
+    sfileno swap_file_number;
     time_t timestamp;
     time_t lastref;
     time_t expires;
@@ -1532,8 +1660,8 @@
 
 /* object to track per-action memory usage (e.g. #idle objects) */
 struct _MemMeter {
-    size_t level;		/* current level (count or volume) */
-    size_t hwater_level;	/* high water mark */
+    ssize_t level;		/* current level (count or volume) */
+    ssize_t hwater_level;	/* high water mark */
     time_t hwater_stamp;	/* timestamp of last high water mark change */
 };
 
@@ -1571,6 +1699,7 @@
 	int n_req;
 	int n_denied;
     } cutoff;
+    int n_established;		/* number of current established connections */
 };
 
 struct _CacheDigest {
@@ -1600,6 +1729,7 @@
     int n_tries;
     struct {
 	unsigned int dont_retry:1;
+	unsigned int ftp_pasv_failed:1;
     } flags;
 };
 
@@ -1673,3 +1803,16 @@
 struct _generic_cbdata {
     void *data;
 };
+
+struct _store_rebuild_data {
+    int objcount;		/* # objects successfully reloaded */
+    int expcount;		/* # objects expired */
+    int scancount;		/* # entries scanned or read from state file */
+    int clashcount;		/* # swapfile clashes avoided */
+    int dupcount;		/* # duplicates purged */
+    int cancelcount;		/* # SWAP_LOG_DEL objects purged */
+    int invalid;		/* # bad lines */
+    int badflags;		/* # bad e->flags */
+    int bad_log_op;
+    int zero_object_sz;
+};
Index: squid/src/tools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/tools.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/tools.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/tools.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: tools.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -48,14 +48,13 @@
 static void fatal_common(const char *);
 static void fatalvf(const char *fmt, va_list args);
 static void mail_warranty(void);
-#if USE_ASYNC_IO
-static AIOCB safeunlinkComplete;
-#endif
 #if MEM_GEN_TRACE
 extern void log_trace_done();
 extern void log_trace_init(char *);
 #endif
 
+extern void (*failure_notify) (const char *);
+
 void
 releaseServerSockets(void)
 {
@@ -191,7 +190,7 @@
     return r->ru_maxrss;
 #elif defined(BSD4_4)
     return r->ru_maxrss;
-#elif HAVE_GETPAGESIZE
+#elif defined(HAVE_GETPAGESIZE) && HAVE_GETPAGESIZE != 0
     return (r->ru_maxrss * getpagesize()) >> 10;
 #elif defined(PAGESIZE)
     return (r->ru_maxrss * PAGESIZE) >> 10;
@@ -216,7 +215,10 @@
 {
     struct rusage rusage;
     squid_getrusage(&rusage);
-    fprintf(debug_log, "CPU Usage: %.3f seconds\n", rusage_cputime(&rusage));
+    fprintf(debug_log, "CPU Usage: %.3f seconds = %.3f user + %.3f sys\n",
+	rusage_cputime(&rusage),
+	rusage.ru_utime.tv_sec + ((double) rusage.ru_utime.tv_usec / 1000000.0),
+	rusage.ru_stime.tv_sec + ((double) rusage.ru_stime.tv_usec / 1000000.0));
     fprintf(debug_log, "Maximum Resident Size: %d KB\n",
 	rusage_maxrss(&rusage));
     fprintf(debug_log, "Page faults with physical i/o: %d\n",
@@ -306,7 +308,7 @@
     syslog(LOG_ALERT, "%s", message);
 #endif
     fprintf(debug_log, "FATAL: %s\n", message);
-    if (opt_debug_stderr && debug_log != stderr)
+    if (opt_debug_stderr > 0 && debug_log != stderr)
 	fprintf(stderr, "FATAL: %s\n", message);
     fprintf(debug_log, "Squid Cache (Version %s): Terminated abnormally.\n",
 	version_string);
@@ -320,10 +322,10 @@
 fatal(const char *message)
 {
     releaseServerSockets();
-    /* check for store_rebuilding flag because fatal() is often
+    /* check for store_dirs_rebuilding because fatal() is often
      * used in early initialization phases, long before we ever
      * get to the store log. */
-    if (!store_rebuilding)
+    if (0 == store_dirs_rebuilding)
 	storeDirWriteCleanLogs(0);
     fatal_common(message);
     exit(shutting_down ? 0 : 1);
@@ -364,6 +366,7 @@
 void
 fatal_dump(const char *message)
 {
+    failure_notify = NULL;
     releaseServerSockets();
     if (message)
 	fatal_common(message);
@@ -411,28 +414,48 @@
     LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1);
     static int present = 0;
     const struct hostent *h = NULL;
-    char *t = NULL;
-
-    if ((t = Config.visibleHostname) != NULL)
-	return t;
-
-    /* Get the host name and store it in host to return */
-    if (!present) {
+    if (Config.visibleHostname != NULL)
+	return Config.visibleHostname;
+    if (present) {
+	(void) 0;
+    } else if (Config.Sockaddr.http->s.sin_addr.s_addr != any_addr.s_addr) {
+	/*
+	 * If the first http_port address has a specific address, try a
+	 * reverse DNS lookup on it.
+	 */
+	host[0] = '\0';
+	h = gethostbyaddr((char *) &Config.Sockaddr.http->s.sin_addr,
+	    sizeof(Config.Sockaddr.http->s.sin_addr), AF_INET);
+	if (h != NULL) {
+	    /* DNS lookup successful */
+	    /* use the official name from DNS lookup */
+	    strcpy(host, h->h_name);
+	    debug(50, 4) ("getMyHostname: resolved tcp_incoming_addr to '%s'\n",
+		host);
+	    present = 1;
+	} else {
+	    debug(50, 6) ("getMyHostname: failed to resolve tcp_incoming_addr\n");
+	}
+    } else {
+	/*
+	 * Get the host name and store it in host to return
+	 */
 	host[0] = '\0';
 	if (gethostname(host, SQUIDHOSTNAMELEN) == -1) {
 	    debug(50, 1) ("getMyHostname: gethostname failed: %s\n",
 		xstrerror());
-	    return NULL;
 	} else {
 	    if ((h = gethostbyname(host)) != NULL) {
+		debug(50, 6) ("getMyHostname: '%s' resolved into '%s'\n",
+		    host, h->h_name);
 		/* DNS lookup successful */
 		/* use the official name from DNS lookup */
 		strcpy(host, h->h_name);
 	    }
-	    present = 1;
 	}
+	present = 1;
     }
-    return host;
+    return present ? host : NULL;
 }
 
 const char *
@@ -444,30 +467,10 @@
 void
 safeunlink(const char *s, int quiet)
 {
-#if USE_ASYNC_IO
-    aioUnlink(s,
-	quiet ? NULL : safeunlinkComplete,
-	quiet ? NULL : xstrdup(s));
-#else
     Counter.syscalls.disk.unlinks++;
     if (unlink(s) < 0 && !quiet)
 	debug(50, 1) ("safeunlink: Couldn't delete %s: %s\n", s, xstrerror());
-#endif
-}
-
-#if USE_ASYNC_IO
-static void
-safeunlinkComplete(int fd, void *data, int retcode, int errcode)
-{
-    char *s = data;
-    if (retcode < 0) {
-	errno = errcode;
-	debug(50, 1) ("safeunlink: Couldn't delete %s. %s\n", s, xstrerror());
-	errno = 0;
-    }
-    xfree(s);
 }
-#endif
 
 /* leave a privilegied section. (Give up any privilegies)
  * Routines that need privilegies can rap themselves in enter_suid()
@@ -479,6 +482,7 @@
 {
     struct passwd *pwd = NULL;
     struct group *grp = NULL;
+    gid_t gid;
     debug(21, 3) ("leave_suid: PID %d called\n", getpid());
     if (geteuid() != 0)
 	return;
@@ -488,12 +492,15 @@
     if ((pwd = getpwnam(Config.effectiveUser)) == NULL)
 	return;
     if (Config.effectiveGroup && (grp = getgrnam(Config.effectiveGroup))) {
-	if (setgid(grp->gr_gid) < 0)
-	    debug(50, 1) ("leave_suid: setgid: %s\n", xstrerror());
+	gid = grp->gr_gid;
     } else {
-	if (setgid(pwd->pw_gid) < 0)
-	    debug(50, 1) ("leave_suid: setgid: %s\n", xstrerror());
+	gid = pwd->pw_gid;
     }
+#if HAVE_SETGROUPS
+    setgroups(1, &gid);
+#endif
+    if (setgid(gid) < 0)
+	debug(50, 1) ("leave_suid: setgid: %s\n", xstrerror());
     debug(21, 3) ("leave_suid: PID %d giving up root, becoming '%s'\n",
 	getpid(), pwd->pw_name);
 #if HAVE_SETRESUID
@@ -553,7 +560,7 @@
 	return;
     enter_suid();
     old_umask = umask(022);
-    fd = file_open(f, O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL);
+    fd = file_open(f, O_WRONLY | O_CREAT | O_TRUNC);
     umask(old_umask);
     leave_suid();
     if (fd < 0) {
@@ -776,6 +783,7 @@
 	list->head = m->next;
     if (m == list->tail)
 	list->tail = m->prev;
+    m->next = m->prev = NULL;
 }
 
 void
@@ -842,3 +850,58 @@
 {
     return (strcspn(s, w_space) != strlen(s));
 }
+
+void
+linklistPush(link_list ** L, void *p)
+{
+    link_list *l = xmalloc(sizeof(*l));
+    l->next = NULL;
+    l->ptr = p;
+    while (*L)
+	L = &(*L)->next;
+    *L = l;
+}
+
+void *
+linklistShift(link_list ** L)
+{
+    void *p;
+    link_list *l;
+    if (NULL == *L)
+	return NULL;
+    l = *L;
+    p = l->ptr;
+    *L = (*L)->next;
+    xfree(l);
+    return p;
+}
+
+
+/*
+ * Same as rename(2) but complains if something goes wrong;
+ * the caller is responsible for handing and explaining the 
+ * consequences of errors.
+ */
+int
+xrename(const char *from, const char *to)
+{
+    debug(21, 2) ("xrename: renaming %s to %s\n", from, to);
+    if (0 == rename(from, to))
+	return 0;
+    debug(21, errno == ENOENT ? 2 : 1) ("xrename: Cannot rename %s to %s: %s\n",
+	from, to, xstrerror());
+    return -1;
+}
+
+int
+stringHasCntl(const char *s)
+{
+    unsigned char c;
+    while ((c = (unsigned char) *s++) != '\0') {
+	if (c <= 0x1f)
+	    return 1;
+	if (c >= 0x7f && c <= 0x9f)
+	    return 1;
+    }
+    return 0;
+}
Index: squid/src/typedefs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/typedefs.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/typedefs.h	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: typedefs.h,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -35,6 +35,7 @@
 typedef unsigned int mem_status_t;
 typedef unsigned int ping_status_t;
 typedef unsigned int swap_status_t;
+typedef int sfileno;
 
 typedef struct {
     size_t bytes;
@@ -70,6 +71,7 @@
 typedef struct _intrange intrange;
 typedef struct _ushortlist ushortlist;
 typedef struct _relist relist;
+typedef struct _sockaddr_in_list sockaddr_in_list;
 typedef struct _SquidConfig SquidConfig;
 typedef struct _SquidConfig2 SquidConfig2;
 typedef struct _close_handler close_handler;
@@ -161,6 +163,8 @@
 typedef struct _helper_server helper_server;
 typedef struct _helper_request helper_request;
 typedef struct _generic_cbdata generic_cbdata;
+typedef struct _storeIOState storeIOState;
+typedef struct _link_list link_list;
 
 #if SQUID_SNMP
 typedef variable_list *(oid_ParseFn) (variable_list *, snint *);
@@ -194,7 +198,10 @@
 typedef void UH(void *data, wordlist *);
 typedef int DEFER(int fd, void *data);
 
-typedef void SIH(int fd, void *);	/* swap in */
+typedef void STIOCB(void *their_data, int errflag, storeIOState *);
+typedef void STRCB(void *their_data, const char *buf, ssize_t len);
+
+typedef void SIH(storeIOState *, void *);	/* swap in */
 typedef int QS(const void *, const void *);	/* qsort */
 typedef void STCB(void *, char *, ssize_t);	/* store callback */
 typedef void STABH(void *);
@@ -204,6 +211,20 @@
 typedef void STVLDCB(void *, int, int);
 typedef void HLPCB(void *, char *buf);
 typedef void HLPCMDOPTS(int *argc, char **argv);
+typedef void IDNSCB(void *, rfc1035_rr *, int);
+
+typedef void STINIT(SwapDir *);
+typedef void STNEWFS(SwapDir *);
+typedef storeIOState *STOBJOPEN(sfileno, mode_t, STIOCB *, void *);
+typedef void STOBJCLOSE(storeIOState *);
+typedef void STOBJREAD(storeIOState *, char *, size_t, off_t, STRCB *, void *);
+typedef void STOBJWRITE(storeIOState *, char *, size_t, off_t, FREE *);
+typedef void STOBJUNLINK(sfileno);
+typedef void STLOGOPEN(SwapDir *);
+typedef void STLOGCLOSE(SwapDir *);
+typedef void STLOGWRITE(const SwapDir *, const StoreEntry *, int);
+typedef int STLOGCLEANOPEN(SwapDir *);
+typedef void STLOGCLEANWRITE(const StoreEntry *, SwapDir *);
 
 typedef double hbase_f(double);
 typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count);
@@ -223,7 +244,7 @@
 typedef int Ctx;
 
 /* in case we want to change it later */
-typedef size_t mb_size_t;
+typedef ssize_t mb_size_t;
 
 /* iteration for HttpHdrRange */
 typedef int HttpHdrRangePos;
Index: squid/src/unlinkd.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/unlinkd.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/unlinkd.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/unlinkd.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,5 +1,5 @@
 /*
- * $Id: unlinkd.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: unlinkd.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 12    Unlink Daemon
  * AUTHOR: Duane Wessels
@@ -51,7 +51,7 @@
     while (fgets(buf, UNLINK_BUF_LEN, stdin)) {
 	if ((t = strchr(buf, '\n')))
 	    *t = '\0';
-#if USE_TRUNCATE_NOT_UNLINK
+#if USE_TRUNCATE
 	x = truncate(buf, 0);
 #else
 	x = unlink(buf);
@@ -188,12 +188,18 @@
     commSetTimeout(unlinkd_rfd, -1, NULL, NULL);
     commSetTimeout(unlinkd_wfd, -1, NULL, NULL);
     /*
-     * We leave unlinkd_wfd blocking, because we never want to lose an
-     * unlink request, and we don't have code to retry if we get
-     * EWOULDBLOCK.
+     * unlinkd_rfd should already be non-blocking because of
+     * ipcCreate.  We change unlinkd_wfd to blocking mode because
+     * we never want to lose an unlink request, and we don't have
+     * code to retry if we get EWOULDBLOCK.  Unfortunately, we can
+     * do this only for the IPC_FIFO case.
      */
-    commSetNonBlocking(unlinkd_rfd);
+    assert(fd_table[unlinkd_rfd].flags.nonblocking);
+    if (FD_PIPE == fd_table[unlinkd_wfd].type)
+	commUnsetNonBlocking(unlinkd_wfd);
     debug(12, 1) ("Unlinkd pipe opened on FD %d\n", unlinkd_wfd);
+#else
+    debug(12, 1) ("Unlinkd is disabled\n");
 #endif
 }
 
Index: squid/src/url.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/url.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/url.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/url.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: url.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: url.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -44,7 +44,17 @@
     "HEAD",
     "CONNECT",
     "TRACE",
-    "PURGE"
+    "PURGE",
+    "OPTIONS",
+    "DELETE",
+    "PROPFIND",
+    "PROPPATCH",
+    "MKCOL",
+    "COPY",
+    "MOVE",
+    "LOCK",
+    "UNLOCK",
+    "ERROR"
 };
 
 const char *ProtocolStr[] =
@@ -112,25 +122,34 @@
     debug(23, 5) ("urlInitialize: Initializing...\n");
     assert(sizeof(ProtocolStr) == (PROTO_MAX + 1) * sizeof(char *));
     memset(&null_request_flags, '\0', sizeof(null_request_flags));
+    /*
+     * These test that our matchDomainName() function works the
+     * way we expect it to.
+     */
+    assert(0 == matchDomainName("foo.com", "foo.com"));
+    assert(0 == matchDomainName(".foo.com", "foo.com"));
+    assert(0 == matchDomainName("foo.com", ".foo.com"));
+    assert(0 == matchDomainName(".foo.com", ".foo.com"));
+    assert(0 == matchDomainName("x.foo.com", ".foo.com"));
+    assert(0 != matchDomainName("x.foo.com", "foo.com"));
+    assert(0 != matchDomainName("foo.com", "x.foo.com"));
+    assert(0 != matchDomainName("bar.com", "foo.com"));
+    assert(0 != matchDomainName(".bar.com", "foo.com"));
+    assert(0 != matchDomainName(".bar.com", ".foo.com"));
+    assert(0 != matchDomainName("bar.com", ".foo.com"));
+    assert(0 < matchDomainName("zzz.com", "foo.com"));
+    assert(0 > matchDomainName("aaa.com", "foo.com"));
+    assert(0 == matchDomainName("FOO.com", "foo.COM"));
+    /* more cases? */
 }
 
 method_t
 urlParseMethod(const char *s)
 {
-    if (strcasecmp(s, "GET") == 0) {
-	return METHOD_GET;
-    } else if (strcasecmp(s, "POST") == 0) {
-	return METHOD_POST;
-    } else if (strcasecmp(s, "PUT") == 0) {
-	return METHOD_PUT;
-    } else if (strcasecmp(s, "HEAD") == 0) {
-	return METHOD_HEAD;
-    } else if (strcasecmp(s, "CONNECT") == 0) {
-	return METHOD_CONNECT;
-    } else if (strcasecmp(s, "TRACE") == 0) {
-	return METHOD_TRACE;
-    } else if (strcasecmp(s, "PURGE") == 0) {
-	return METHOD_PURGE;
+    method_t method = METHOD_NONE;
+    for (method++; method < METHOD_ENUM_END; method++) {
+	if (0 == strcasecmp(s, RequestMethodStr[method]))
+	    return method;
     }
     return METHOD_NONE;
 }
@@ -197,6 +216,7 @@
     LOCAL_ARRAY(char, urlpath, MAX_URL);
     request_t *request = NULL;
     char *t = NULL;
+    char *q = NULL;
     int port;
     protocol_t protocol = PROTO_NONE;
     int l;
@@ -263,12 +283,21 @@
 	case URI_WHITESPACE_ALLOW:
 	    break;
 	case URI_WHITESPACE_ENCODE:
-	    t = rfc1738_escape(urlpath);
+	    t = rfc1738_escape_unescaped(urlpath);
 	    xstrncpy(urlpath, t, MAX_URL);
 	    break;
 	case URI_WHITESPACE_CHOP:
 	    *(urlpath + strcspn(urlpath, w_space)) = '\0';
 	    break;
+	case URI_WHITESPACE_STRIP:
+	default:
+	    t = q = urlpath;
+	    while (*t) {
+		if (!xisspace(*t))
+		    *q++ = *t;
+		t++;
+	    }
+	    *q = '\0';
 	}
     }
     request = requestCreate(method, protocol, urlpath);
@@ -356,26 +385,83 @@
 	    break;
 	}
     }
-    if (stringHasWhitespace(buf))
-	xstrncpy(buf, rfc1738_escape(buf), MAX_URL);
+    if (stringHasCntl(buf))
+	xstrncpy(buf, rfc1738_escape_unescaped(buf), MAX_URL);
     return buf;
 }
 
+/*
+ * matchDomainName() compares a hostname with a domainname according
+ * to the following rules:
+ * 
+ *    HOST          DOMAIN        MATCH?
+ * ------------- -------------    ------
+ *    foo.com       foo.com         YES
+ *   .foo.com       foo.com         YES
+ *  x.foo.com       foo.com          NO
+ *    foo.com      .foo.com         YES
+ *   .foo.com      .foo.com         YES
+ *  x.foo.com      .foo.com         YES
+ *
+ *  We strip leading dots on hosts (but not domains!) so that
+ *  ".foo.com" is is always the same as "foo.com".
+ *
+ *  Return values:
+ *     0 means the host matches the domain
+ *     1 means the host is greater than the domain
+ *    -1 means the host is less than the domain
+ */
+
 int
-matchDomainName(const char *domain, const char *host)
+matchDomainName(const char *h, const char *d)
 {
-    int offset;
-    if ((offset = strlen(host) - strlen(domain)) < 0)
-	return 0;		/* host too short */
-    if (strcasecmp(domain, host + offset) != 0)
-	return 0;		/* no match at all */
-    if (*domain == '.')
-	return 1;
-    if (offset == 0)
-	return 1;
-    if (*(host + offset - 1) == '.')
-	return 1;
-    return 0;
+    int dl;
+    int hl;
+    while ('.' == *h)
+	h++;
+    hl = strlen(h);
+    dl = strlen(d);
+    /*
+     * Start at the ends of the two strings and work towards the
+     * beginning.
+     */
+    while (xtolower(h[--hl]) == xtolower(d[--dl])) {
+	if (hl == 0 && dl == 0) {
+	    /*
+	     * We made it all the way to the beginning of both
+	     * strings without finding any difference.
+	     */
+	    return 0;
+	}
+	if (0 == hl) {
+	    /* 
+	     * The host string is shorter than the domain string.
+	     * There is only one case when this can be a match.
+	     * If the domain is just one character longer, and if
+	     * that character is a leading '.' then we call it a
+	     * match.
+	     */
+	    if (1 == dl && '.' == d[0])
+		return 0;
+	    else
+		return -1;
+	}
+	if (0 == dl) {
+	    /*
+	     * The domain string is shorter than the host string.
+	     * This is a match only if the first domain character
+	     * is a leading '.'.
+	     */
+	    if ('.' == d[0])
+		return 0;
+	    else
+		return 1;
+	}
+    }
+    /*
+     * We found different characters in the same position (from the end).
+     */
+    return (xtolower(h[hl]) - xtolower(d[dl]));
 }
 
 int
@@ -393,7 +479,6 @@
     switch (r->protocol) {
     case PROTO_URN:
     case PROTO_HTTP:
-    case PROTO_HTTPS:
     case PROTO_CACHEOBJ:
 	rc = 1;
 	break;
@@ -408,6 +493,13 @@
 	else if (r->method == METHOD_HEAD)
 	    rc = 1;
 	break;
+    case PROTO_HTTPS:
+	/*
+	 * Squid can't originate an SSL connection, so it should
+	 * never receive an "https:" URL.  It should always be
+	 * CONNECT instead.
+	 */
+	rc = 0;
     default:
 	break;
     }
Index: squid/src/urn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/urn.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/urn.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/urn.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,7 +1,7 @@
 
 /*
  *
- * $Id: urn.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: urn.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 52    URN Parsing
  * AUTHOR: Kostas Anagnostakis
@@ -138,7 +138,7 @@
     if ((urlres_e = storeGetPublic(urlres, METHOD_GET)) == NULL) {
 	urlres_e = storeCreateEntry(urlres, urlres, null_request_flags, METHOD_GET);
 	storeClientListAdd(urlres_e, urnState);
-	fwdStart(-1, urlres_e, urlres_r, no_addr, no_addr);
+	fwdStart(-1, urlres_e, urlres_r);
     } else {
 	storeLockObject(urlres_e);
 	storeClientListAdd(urlres_e, urnState);
@@ -217,7 +217,7 @@
     }
     s = buf + k;
     assert(urlres_e->mem_obj->reply);
-    httpReplyParse(urlres_e->mem_obj->reply, buf);
+    httpReplyParse(urlres_e->mem_obj->reply, buf, k);
     debug(52, 3) ("mem->reply exists, code=%d.\n",
 	urlres_e->mem_obj->reply->sline.status);
     if (urlres_e->mem_obj->reply->sline.status != HTTP_OK) {
Index: squid/src/useragent.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/useragent.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/src/useragent.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/useragent.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: useragent.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: useragent.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 40    User-Agent logging
  * AUTHOR: Joe Ramey <ramey@csc.ti.com>
@@ -50,7 +50,7 @@
 	cache_useragent_log = NULL;
     }
     if (fname && strcmp(fname, "none") != 0) {
-	log_fd = file_open(fname, O_WRONLY | O_CREAT | O_APPEND, NULL, NULL, NULL);
+	log_fd = file_open(fname, O_WRONLY | O_CREAT | O_APPEND);
 	if (log_fd < 0) {
 	    debug(50, 0) ("useragentOpenLog: %s: %s\n", fname, xstrerror());
 	} else if ((cache_useragent_log = fdopen(log_fd, "a")) == NULL) {
@@ -87,7 +87,7 @@
 	i--;
 	snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-	rename(from, to);
+	xrename(from, to);
     }
     if (cache_useragent_log) {
 	file_close(fileno(cache_useragent_log));
@@ -97,7 +97,7 @@
     /* Rotate the current log to .0 */
     if (Config.Log.rotateNumber > 0) {
 	snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-	rename(fname, to);
+	xrename(fname, to);
     }
     useragentOpenLog();
 #endif
Index: squid/src/wccp.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/wccp.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1
diff -u -r1.1 -r1.1.1.1
--- squid/src/wccp.c	26 Jan 2000 03:25:01 -0000	1.1
+++ squid/src/wccp.c	26 Jan 2000 03:25:01 -0000	1.1.1.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: wccp.c,v 1.1 2000/01/26 03:25:01 hno Exp $
+ * $Id: wccp.c,v 1.1.1.1 2000/01/26 03:25:01 hno Exp $
  *
  * DEBUG: section 80     WCCP Support
  * AUTHOR: Glenn Chisholm
Index: squid/test-suite/tcp-banger2.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/test-suite/tcp-banger2.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.3
diff -u -r1.1.1.2 -r1.1.1.3
--- squid/test-suite/tcp-banger2.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/test-suite/tcp-banger2.c	26 Jan 2000 03:25:01 -0000	1.1.1.3
@@ -1,6 +1,6 @@
 #include "config.h"
 
-/* $Id: tcp-banger2.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $ */
+/* $Id: tcp-banger2.c,v 1.1.1.3 2000/01/26 03:25:01 hno Exp $ */
 
 /*
  * On some systems, FD_SETSIZE is set to something lower than the
