--------------------- PatchSet 7 Date: 2000/02/04 16:41:12 Author: hno Branch: hno-2_2 Tag: (none) Log: Imported my squid-2.2.STABLE5-hno.20000202.snapshot. Had planned on importing every patch separately, but I never get the time to do it, so instead of waiting indefinitely on getting this going the SourceForge repository starts with the 2.2.STABLE-hno snapshot from 2000-02-02. Members: auth_modules/NCSA/ncsa_auth.c:1.1.1.1->1.1.1.1.6.1 auth_modules/SMB/Makefile:1.1.1.1->1.1.1.1.2.1 auth_modules/SMB/smb_auth.c:1.1.1.1->1.1.1.1.2.1 auth_modules/getpwnam/getpwnam_auth.c:1.1.1.1->1.1.1.1.6.1 cfgaux/config.guess:1.1.1.2->1.1.1.2.2.1 cfgaux/config.sub:1.1.1.2->1.1.1.2.2.1 include/autoconf.h.in:1.1.1.2->1.1.1.2.2.1 include/config.h.in:1.1.1.2->1.1.1.2.2.1 include/splay.h:1.1.1.1->1.1.1.1.2.1 include/util.h:1.1.1.2->1.1.1.2.2.1 include/version.h:1.1.1.2->1.1.1.2.2.1 lib/rfc1123.c:1.1.1.2->1.1.1.2.2.1 lib/rfc1738.c:1.1.1.1->1.1.1.1.2.1 lib/splay.c:1.1.1.1->1.1.1.1.2.1 src/HttpHeader.c:1.1.1.2->1.1.1.2.2.1 src/HttpMsg.c:1.1.1.1->1.1.1.1.6.1 src/HttpReply.c:1.1.1.2->1.1.1.2.2.1 src/HttpRequest.c:1.1.1.2->1.1.1.2.2.1 src/access_log.c:1.1.1.2->1.1.1.2.2.1 src/acl.c:1.1.1.2->1.1.1.2.2.1 src/aiops.c:1.1.1.2->1.1.1.2.2.1 src/asn.c:1.1.1.2->1.1.1.2.2.1 src/async_io.c:1.1.1.2->1.1.1.2.2.1 src/authenticate.c:1.1.1.2->1.1.1.2.2.1 src/cache_cf.c:1.1.1.2->1.1.1.2.2.1 src/cf.data.pre:1.1.1.2->1.1.1.2.2.1 src/client_side.c:1.1.1.2->1.1.1.2.2.1 src/comm.c:1.1.1.2->1.1.1.2.2.1 src/comm_select.c:1.1.1.2->1.1.1.2.2.1 src/defines.h:1.1.1.2->1.1.1.2.2.1 src/delay_pools.c:1.1.1.2->1.1.1.2.2.1 src/disk.c:1.1.1.2->1.1.1.2.2.1 src/dns.c:1.1.1.2->1.1.1.2.2.1 src/dnsserver.c:1.1.1.2->1.1.1.2.2.1 src/enums.h:1.1.1.2->1.1.1.2.2.1 src/errorpage.c:1.1.1.2->1.1.1.2.2.1 src/event.c:1.1.1.2->1.1.1.2.2.1 src/forward.c:1.1.1.2->1.1.1.2.2.1 src/ftp.c:1.1.1.2->1.1.1.2.2.1 src/gopher.c:1.1.1.2->1.1.1.2.2.1 src/helper.c:1.1.1.2->1.1.1.2.2.1 src/http.c:1.1.1.2->1.1.1.2.2.1 src/icmp.c:1.1.1.2->1.1.1.2.6.1 src/internal.c:1.1.1.2->1.1.1.2.2.1 src/ipc.c:1.1.1.2->1.1.1.2.2.1 src/ipcache.c:1.1.1.2->1.1.1.2.2.1 src/main.c:1.1.1.2->1.1.1.2.2.1 src/neighbors.c:1.1.1.2->1.1.1.2.2.1 src/net_db.c:1.1.1.2->1.1.1.2.2.1 src/peer_digest.c:1.1.1.2->1.1.1.2.2.1 src/peer_select.c:1.1.1.2->1.1.1.2.2.1 src/protos.h:1.1.1.2->1.1.1.2.2.1 src/pump.c:1.1.1.2->1.1.1.2.2.1 src/redirect.c:1.1.1.2->1.1.1.2.2.1 src/send-announce.c:1.1.1.2->1.1.1.2.2.1 src/squid.h:1.1.1.2->1.1.1.2.2.1 src/ssl.c:1.1.1.2->1.1.1.2.2.1 src/stat.c:1.1.1.2->1.1.1.2.2.1 src/store.c:1.1.1.2->1.1.1.2.2.1 src/store_client.c:1.1.1.2->1.1.1.2.2.1 src/store_dir.c:1.1.1.2->1.1.1.2.2.1 src/store_log.c:1.1.1.1->1.1.1.1.2.1 src/store_rebuild.c:1.1.1.2->1.1.1.2.2.1 src/structs.h:1.1.1.2->1.1.1.2.2.1 src/tools.c:1.1.1.2->1.1.1.2.2.1 src/typedefs.h:1.1.1.2->1.1.1.2.2.1 src/unlinkd.c:1.1.1.2->1.1.1.2.2.1 src/url.c:1.1.1.2->1.1.1.2.2.1 src/urn.c:1.1.1.2->1.1.1.2.2.1 Index: squid/auth_modules/NCSA/ncsa_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/auth_modules/NCSA/Attic/ncsa_auth.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.6.1 diff -u -r1.1.1.1 -r1.1.1.1.6.1 --- squid/auth_modules/NCSA/ncsa_auth.c 26 Jan 2000 03:21:46 -0000 1.1.1.1 +++ squid/auth_modules/NCSA/ncsa_auth.c 4 Feb 2000 16:41:12 -0000 1.1.1.1.6.1 @@ -130,6 +130,8 @@ printf("ERR\n"); continue; } + rfc1738_unescape(user); + rfc1738_unescape(passwd); u = hash_lookup(hash, user); if (u == NULL) { printf("ERR\n"); Index: squid/auth_modules/SMB/Makefile =================================================================== RCS file: /cvsroot/squid-sf//squid/auth_modules/SMB/Attic/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- squid/auth_modules/SMB/Makefile 26 Jan 2000 03:23:09 -0000 1.1.1.1 +++ squid/auth_modules/SMB/Makefile 4 Feb 2000 16:41:12 -0000 1.1.1.1.2.1 @@ -20,10 +20,11 @@ CC = gcc CFLAGS = -O2 -Wall \ - -DSAMBAPREFIX=\"$(SAMBAPREFIX)\" -DHELPERSCRIPT=\"$(INSTALLBIN)/$(SCRIPT)\" + -DSAMBAPREFIX=\"$(SAMBAPREFIX)\" -DHELPERSCRIPT=\"$(INSTALLBIN)/$(SCRIPT)\" \ + -I../../include smb_auth: $(OBJECTS) - $(CC) -o smb_auth $(OBJECTS) + $(CC) -o smb_auth $(OBJECTS) -L../../lib -lmiscutil -lm install: smb_auth install smb_auth $(SCRIPT) $(INSTALLBIN) 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.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- 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 4 Feb 2000 16:41:12 -0000 1.1.1.1.2.1 @@ -21,6 +21,8 @@ #include #include +#include "util.h" + #define BUFSIZE 256 #define NMB_UNICAST 1 #define NMB_BROADCAST 2 @@ -155,6 +157,9 @@ continue; } + rfc1738_unescape(user); + rfc1738_unescape(pass); + (void) fprintf(p, "%s\n", SAMBAPREFIX); (void) fprintf(p, "%s\n", dom->name); (void) fprintf(p, "%s\n", dom->nmbaddr); Index: squid/auth_modules/getpwnam/getpwnam_auth.c =================================================================== RCS file: /cvsroot/squid-sf//squid/auth_modules/getpwnam/Attic/getpwnam_auth.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.6.1 diff -u -r1.1.1.1 -r1.1.1.1.6.1 --- squid/auth_modules/getpwnam/getpwnam_auth.c 26 Jan 2000 03:23:09 -0000 1.1.1.1 +++ squid/auth_modules/getpwnam/getpwnam_auth.c 4 Feb 2000 16:41:12 -0000 1.1.1.1.6.1 @@ -40,6 +40,7 @@ #include #endif +#include "util.h" #define ERR "ERR\n" #define OK "OK\n" @@ -65,6 +66,8 @@ printf(ERR); continue; } + rfc1738_unescape(user); + rfc1738_unescape(passwd); pwd = getpwnam(user); if (pwd == NULL) { printf(ERR); 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/cfgaux/config.guess 26 Jan 2000 03:23:09 -0000 1.1.1.2 +++ squid/cfgaux/config.guess 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -1,6 +1,7 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 +# Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -23,6 +24,7 @@ # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to the Autoconf mailing list . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and @@ -35,6 +37,20 @@ # (but try to keep the structure clean). # +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then @@ -46,17 +62,66 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` + cat <$dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 @@ -68,12 +133,39 @@ echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) - echo m68k-cbm-openbsd${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; - Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 @@ -81,9 +173,12 @@ echo pyramid-pyramid-bsd fi exit 0 ;; - NILE:*:*:dcosx) + NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; @@ -108,6 +203,18 @@ sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; @@ -115,23 +222,58 @@ echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) - echo m68k-atari-openbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) - echo m68k-sun-openbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) - echo m68k-apple-openbsd${UNAME_RELEASE} + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; @@ -141,9 +283,16 @@ VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >dummy.c - int main (argc, argv) int argc; char **argv; { + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); @@ -158,10 +307,10 @@ exit (-1); } EOF - ${CC-cc} dummy.c -o dummy \ - && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) @@ -213,7 +362,7 @@ exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include main() @@ -224,8 +373,8 @@ exit(0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -234,7 +383,8 @@ fi exit 0 ;; *:AIX:*:4) - if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -267,18 +417,50 @@ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; - 9000/[3478]??:HP-UX:*:*) + 9000/[34678]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; - 9000/8?? ) HP_ARCH=hppa1.0 ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include int main () @@ -303,8 +485,8 @@ exit (0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -313,6 +495,9 @@ 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; @@ -329,6 +514,9 @@ parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -361,11 +549,14 @@ CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} exit 0 ;; + CRAY*T3E:*:*:*) + echo t3e-cray-unicosmk${UNAME_RELEASE} + exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) - FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; @@ -375,13 +566,25 @@ hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; - hp3[0-9][05]:OpenBSD:*:*) - echo m68k-hp-openbsd${UNAME_RELEASE} + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - i?86:BSD/386:*:* | *:BSD/OS:*:*) + i?86:BSD/386:*:* | i?86:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; *:FreeBSD:*:*) + if test -x /usr/bin/objformat; then + if test "elf" = "`/usr/bin/objformat`"; then + echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` + exit 0 + fi + fi echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) @@ -391,64 +594,208 @@ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) - echo i386-pc-cygwin32 + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin32 + echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) + # uname on the ARM produces all sorts of strangeness, and we need to + # filter it out. + case "$UNAME_MACHINE" in + armv*) UNAME_MACHINE=$UNAME_MACHINE ;; + arm* | sa110*) UNAME_MACHINE="arm" ;; + esac + # The BFD linker knows what the default object file format is, so - # first see if it will tell us. - ld_help_string=`ld --help 2>&1` - if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then - echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then - echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then - echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then - echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 - elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then - echo "powerpc-unknown-linux-gnu" ; exit 0 - elif test "${UNAME_MACHINE}" = "alpha" ; then - echo alpha-unknown-linux-gnu ; exit 0 - elif test "${UNAME_MACHINE}" = "sparc" ; then - echo sparc-unknown-linux-gnu ; exit 0 - else - # Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us - # useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout. - test ! -d /usr/lib/ldscripts/. \ - && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 - # Determine whether the default compiler is a.out or elf - cat >dummy.c <&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <$dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __ELF__ - printf ("%s-pc-linux-gnu\n", argv[1]); +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif #else - printf ("%s-pc-linux-gnuaout\n", argv[1]); + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF - ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} @@ -456,6 +803,14 @@ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; + i?86:*:5:7*) + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585 + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE} + exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; @@ -506,7 +870,7 @@ mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i?86:LynxOS:2.*:*) + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) @@ -518,6 +882,9 @@ SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; @@ -529,6 +896,10 @@ echo ns32k-sni-sysv fi exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -541,29 +912,43 @@ mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; - R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; - PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - news*:NEWS-OS:[56].*:*) - echo mips-sony-newsos${UNAME_RELEASE} + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; - i?86:OS/2:*:*) - echo ${UNAME_MACHINE}-ibm-os2 + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -cat >dummy.c <$dummy.c < # include @@ -601,7 +986,10 @@ #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif @@ -661,8 +1049,8 @@ } EOF -${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 -rm -f dummy.c dummy +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy # Apollos put the system type in the environment. 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/cfgaux/config.sub 26 Jan 2000 03:23:09 -0000 1.1.1.2 +++ squid/cfgaux/config.sub 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -1,6 +1,6 @@ #! /bin/sh # Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. +# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. @@ -98,11 +98,21 @@ os= basic_machine=$1 ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=vxworks + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; -sco5) - os=sco3.2v5 + os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) @@ -121,6 +131,9 @@ os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -149,19 +162,27 @@ case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ - | arme[lb] | pyramid \ - | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ - | alpha | we32k | ns16k | clipper | i370 | sh \ - | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ - | pdp11 | mips64el | mips64orion | mips64orionel \ - | sparc | sparclet | sparclite | sparc64) + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v) basic_machine=$basic_machine-unknown ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65) + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. - i[3456]86) + i[34567]86) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. @@ -170,23 +191,44 @@ exit 1 ;; # Recognize the basic CPU types with company name. - vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ - | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ - | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ - | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ - | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* | f301-* | iE86-*) + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ + | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* \ + | f301-* | armv*-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* ) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; alliant | fx80) basic_machine=fx80-alliant ;; @@ -204,9 +246,9 @@ amiga | amiga-*) basic_machine=m68k-cbm ;; - amigados) + amigaos | amigados) basic_machine=m68k-cbm - os=-amigados + os=-amigaos ;; amigaunix | amix) basic_machine=m68k-cbm @@ -216,6 +258,10 @@ basic_machine=m68k-apollo os=-sysv ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; aux) basic_machine=m68k-apple os=-aux @@ -292,6 +338,10 @@ encore | umax | mmax) basic_machine=ns32k-encore ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; fx2800) basic_machine=i860-alliant ;; @@ -310,6 +360,14 @@ basic_machine=h8300-hitachi os=-hms ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; harris) basic_machine=m88k-harris os=-sysv3 @@ -325,13 +383,30 @@ basic_machine=m68k-hp os=-hpux ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; - hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) @@ -340,27 +415,51 @@ hppa-next) os=-nextstep3 ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[3456]86v32) + i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[3456]86v4*) + i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[3456]86v) + i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[3456]86sol2) + i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -378,9 +477,6 @@ m88k-omron*) basic_machine=m88k-omron ;; - mab-next) - os=-nextstep3 - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -392,16 +488,44 @@ miniframe) basic_machine=m68000-convergent ;; + *mint | *MiNT) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-corel + os=-linux + ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos @@ -414,6 +538,10 @@ basic_machine=mips-sony os=-newsos ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; next | m*-next ) basic_machine=m68k-next case $os in @@ -439,9 +567,25 @@ basic_machine=i960-intel os=-nindy ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; np1) basic_machine=np1-gould ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -459,25 +603,23 @@ pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5) - basic_machine=i586-intel + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86) + basic_machine=i686-pc ;; - pentiumpro | p6) - basic_machine=i686-intel + pentiumii | pentium2) + basic_machine=i786-pc ;; - pentium-* | p5-*) + pentium-* | p5-* | k5-* | k6-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-*) + pentiumpro-* | p6-* | 6x86-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - k5) - # We don't have specific support for AMD's K5 yet, so just call it a Pentium - basic_machine=i586-amd - ;; - nexen) - # We don't have specific support for Nexgen yet, so just call it a Pentium - basic_machine=i586-nexgen + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -497,12 +639,20 @@ ps2) basic_machine=i386-ibm ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; sequent) basic_machine=i386-sequent ;; @@ -510,6 +660,10 @@ basic_machine=sh-hitachi os=-hms ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; sps7) basic_machine=m68k-bull os=-sysv2 @@ -517,6 +671,13 @@ spur) basic_machine=spur-unknown ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; sun2) basic_machine=m68000-sun ;; @@ -561,6 +722,16 @@ basic_machine=i386-sequent os=-dynix ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; tower | tower-32) basic_machine=m68k-ncr ;; @@ -572,6 +743,10 @@ basic_machine=a29k-nyu os=-sym1 ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; vaxv) basic_machine=vax-dec os=-sysv @@ -580,7 +755,7 @@ basic_machine=vax-dec os=-vms ;; - vpp*|vx|vx-*) + vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) @@ -595,6 +770,14 @@ basic_machine=a29k-wrs os=-vxworks ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; xmp) basic_machine=xmp-cray os=-unicos @@ -602,6 +785,10 @@ xps | xps100) basic_machine=xps100-honeywell ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -609,8 +796,21 @@ # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; mips) - basic_machine=mips-mips + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi ;; romp) basic_machine=romp-ibm @@ -627,7 +827,7 @@ we32k) basic_machine=we32k-att ;; - sparc) + sparc | sparcv9) basic_machine=sparc-sun ;; cydra) @@ -639,6 +839,16 @@ orion105) basic_machine=clipper-highlevel ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -671,9 +881,12 @@ -solaris) os=-solaris2 ;; - -unixware* | svr4*) + -svr4*) os=-sysv4 ;; + -unixware*) + os=-sysv4.2uw + ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; @@ -684,17 +897,26 @@ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -linux-gnu* | -uxpv*) + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -719,6 +941,9 @@ -acis*) os=-aos ;; + -386bsd) + os=-bsd + ;; -ctix* | -uts*) os=-sysv ;; @@ -750,12 +975,19 @@ # This must come after -sysvr4. -sysv*) ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; -xenix) os=-xenix ;; - -none) + -*mint | -*MiNT) + os=-mint ;; - -os2) + -none) ;; *) # Get rid of the `-' at the beginning of $os. @@ -780,6 +1012,9 @@ *-acorn) os=-riscix1.2 ;; + arm*-corel) + os=-linux + ;; arm*-semi) os=-aout ;; @@ -801,15 +1036,36 @@ # default. # os=-sunos4 ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; + *-be) + os=-beos + ;; *-ibm) os=-aix ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; *-hp) os=-hpux ;; @@ -820,7 +1076,7 @@ os=-sysv ;; *-cbm) - os=-amigados + os=-amigaos ;; *-dg) os=-dgux @@ -873,6 +1129,18 @@ f301-fujitsu) os=-uxpv ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; *) os=-none ;; @@ -894,9 +1162,15 @@ -aix*) vendor=ibm ;; + -beos*) + vendor=be + ;; -hpux*) vendor=hp ;; + -mpeix*) + vendor=hp + ;; -hiux*) vendor=hitachi ;; @@ -924,6 +1198,15 @@ -aux*) vendor=apple ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/include/autoconf.h.in 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/include/autoconf.h.in 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -70,6 +70,9 @@ /* Define to use async disk I/O operations */ #undef USE_ASYNC_IO +/* Number of worker theads for async-io */ +#undef NR_ASYNC_IO_THREADS + /* * If you want to use Squid's ICMP features (highly recommended!) then * define this. When USE_ICMP is defined, Squid will send ICMP pings @@ -136,6 +139,11 @@ */ #undef USE_CARP +/* + * Optimistic I/O + */ +#undef OPTIMISTIC_IO + /* Define if struct tm has tm_gmtoff member */ #undef HAVE_TM_GMTOFF @@ -246,6 +254,15 @@ */ #undef HAVE_STATVFS +/* Default HTTP port */ +#undef CACHE_HTTP_PORT + +/* Default ICP port */ +#undef CACHE_ICP_PORT + +/* Allow _ in hostnames */ +#undef ALLOW_HOSTNAME_UNDERSCORES + /* * we check for struct mallinfo */ @@ -350,6 +367,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 @@ -365,12 +385,18 @@ /* Define if you have the snprintf function. */ #undef HAVE_SNPRINTF +/* Define if you have the socketpair function. */ +#undef HAVE_SOCKETPAIR + /* Define if you have the srand48 function. */ #undef HAVE_SRAND48 /* Define if you have the srandom function. */ #undef HAVE_SRANDOM +/* Define if you have the statfs function. */ +#undef HAVE_STATFS + /* Define if you have the strerror function. */ #undef HAVE_STRERROR @@ -524,6 +550,9 @@ /* Define if you have the header file. */ #undef HAVE_SYS_IOCTL_H +/* Define if you have the header file. */ +#undef HAVE_SYS_MOUNT_H + /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/include/config.h.in 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/include/config.h.in 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * AUTHOR: Duane Wessels * @@ -119,11 +119,11 @@ #endif #if !defined(CACHE_HTTP_PORT) -#define CACHE_HTTP_PORT @CACHE_HTTP_PORT@ +#define CACHE_HTTP_PORT 3128 #endif #if !defined(CACHE_ICP_PORT) -#define CACHE_ICP_PORT @CACHE_ICP_PORT@ +#define CACHE_ICP_PORT 3130 #endif #if !defined(CACHEMGR_HOSTNAME) @@ -162,12 +162,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 @@ -192,4 +186,18 @@ #endif #define NUM32LEN sizeof(num32) /* this should always be 4 */ +/* Async-IO tuning */ +#if USE_ASYNC_IO +#ifdef _SQUID_LINUX_ +#define USE_ASYNC_IO_CLOSE 0 +#else +#define USE_ASYNC_IO_CLOSE 1 +#endif +#define USE_ASYNC_IO_OPEN 1 +#define USE_ASYNC_IO_UNLINK 0 +#define USE_ASYNC_IO_READ 1 +#define USE_ASYNC_IO_WRITE 0 +#define USE_ASYNC_IO_STAT 1 +#endif + #endif /* _CONFIG_H_ */ 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.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- squid/include/splay.h 26 Jan 2000 03:21:47 -0000 1.1.1.1 +++ squid/include/splay.h 4 Feb 2000 16:41:12 -0000 1.1.1.1.2.1 @@ -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.1.2.1 2000/02/04 16:41:12 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/include/util.h 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/include/util.h 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/include/version.h 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/include/version.h 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -1,10 +1,10 @@ /* - * $Id: version.h,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $ + * $Id: version.h,v 1.1.1.2.2.1 2000/02/04 16:41:12 hno Exp $ * * SQUID_VERSION - String for version id of this distribution */ #ifndef SQUID_VERSION -#define SQUID_VERSION "2.2.STABLE5" +#define SQUID_VERSION "2.2.STABLE5-hno.20000202" #endif #ifndef SQUID_RELEASE_TIME 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/lib/rfc1123.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/lib/rfc1123.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: * AUTHOR: Harvest Derived @@ -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.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- squid/lib/rfc1738.c 26 Jan 2000 03:21:47 -0000 1.1.1.1 +++ squid/lib/rfc1738.c 4 Feb 2000 16:41:12 -0000 1.1.1.1.2.1 @@ -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.1.2.1 2000/02/04 16:41:12 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 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 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 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" */ 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.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- squid/lib/splay.c 26 Jan 2000 03:21:47 -0000 1.1.1.1 +++ squid/lib/splay.c 4 Feb 2000 16:41:12 -0000 1.1.1.1.2.1 @@ -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.1.2.1 2000/02/04 16:41:12 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; @@ -115,25 +115,38 @@ { 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 +160,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 +177,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/src/HttpHeader.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpHeader.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/HttpHeader.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/HttpHeader.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 55 HTTP Header * AUTHOR: Alex Rousskov @@ -383,9 +383,22 @@ HttpHeaderStats[hdr->owner].parsedCount++; /* commonn format headers are ":[ws]" lines delimited by */ while (field_start < header_end) { - const char *field_end = field_start + strcspn(field_start, "\r\n"); + const char *field_end = field_start; + do { + field_end = field_end + strcspn(field_end, "\r\n"); + /* skip CRLF */ + if (*field_end == '\r') + field_end++; + if (*field_end == '\n') + field_end++; + } while (*field_end == ' ' || *field_end == '\t'); if (!*field_end || field_end > header_end) return httpHeaderReset(hdr); /* missing */ + /* back up over CRLF */ + if (field_end > field_start && field_end[-1] == '\n') + field_end--; + if (field_end > field_start && field_end[-1] == '\r') + field_end--; e = httpHeaderEntryParseCreate(field_start, field_end); if (e != NULL) httpHeaderAddEntry(hdr, e); Index: squid/src/HttpMsg.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpMsg.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.6.1 diff -u -r1.1.1.1 -r1.1.1.1.6.1 --- squid/src/HttpMsg.c 26 Jan 2000 03:21:47 -0000 1.1.1.1 +++ squid/src/HttpMsg.c 4 Feb 2000 16:41:12 -0000 1.1.1.1.6.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpMsg.c,v 1.1.1.1 2000/01/26 03:21:47 hno Exp $ + * $Id: HttpMsg.c,v 1.1.1.1.6.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 74 HTTP Message * AUTHOR: Alex Rousskov @@ -91,7 +91,12 @@ int httpMsgIsPersistent(float http_ver, const HttpHeader * hdr) { - if (http_ver >= 1.1) { + if (Config.Timeout.pconn < 10) { + /* + * Persistent connections are disabled by configuration + */ + return 0; + } else if (http_ver >= 1.1) { /* * for modern versions of HTTP: persistent unless there is * a "Connection: close" header. 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/HttpReply.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/HttpReply.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 58 HTTP Reply (Response) * AUTHOR: Alex Rousskov @@ -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, size_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; 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/HttpRequest.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/HttpRequest.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 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->client_addr = no_addr; + req->my_addr = no_addr; + req->lastmod = -1; httpHeaderInit(&req->header, hoRequest); return req; } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/access_log.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/access_log.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 46 Access Log * AUTHOR: Duane Wessels @@ -38,7 +38,6 @@ #include "squid.h" static void accessLogOpen(const char *fname); -static char *log_quote(const char *header); static void accessLogSquid(AccessLogEntry * al, MemBuf * mb); static void accessLogCommon(AccessLogEntry * al, MemBuf * mb); @@ -114,7 +113,7 @@ /* log_quote -- URL-style encoding on MIME headers. */ -static char * +char * log_quote(const char *header) { int c; @@ -135,8 +134,18 @@ * more readable. */ while ((c = *(const unsigned char *) header++) != '\0') { +#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 == '%' @@ -151,12 +160,18 @@ || 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; } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/acl.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/acl.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -175,9 +175,13 @@ return ACL_URL_REGEX; if (!strcmp(s, "port")) return ACL_URL_PORT; + if (!strcmp(s, "myport")) + return ACL_MY_PORT; #if USE_IDENT if (!strcmp(s, "ident")) return ACL_IDENT; + if (!strcmp(s, "ident_regex")) + return ACL_IDENT_REGEX; #endif if (!strncmp(s, "proto", 5)) return ACL_PROTO; @@ -187,6 +191,8 @@ return ACL_BROWSER; if (!strcmp(s, "proxy_auth")) return ACL_PROXY_AUTH; + if (!strcmp(s, "proxy_auth_regex")) + return ACL_PROXY_AUTH_REGEX; if (!strcmp(s, "src_as")) return ACL_SRC_ASN; if (!strcmp(s, "dst_as")) @@ -229,9 +235,13 @@ return "url_regex"; if (type == ACL_URL_PORT) return "port"; + if (type == ACL_MY_PORT) + return "myport"; #if USE_IDENT if (type == ACL_IDENT) return "ident"; + if (type == ACL_IDENT_REGEX) + return "ident_regex"; #endif if (type == ACL_PROTO) return "proto"; @@ -241,6 +251,8 @@ return "browser"; if (type == ACL_PROXY_AUTH) return "proxy_auth"; + if (type == ACL_PROXY_AUTH_REGEX) + return "proxy_auth_regex"; if (type == ACL_SRC_ASN) return "src_as"; if (type == ACL_DST_ASN) @@ -704,12 +716,16 @@ aclParseIntlist(&A->data); break; case ACL_URL_PORT: + case ACL_MY_PORT: aclParseIntRange(&A->data); break; #if USE_IDENT case ACL_IDENT: aclParseWordList(&A->data); break; + case ACL_IDENT_REGEX: + aclParseRegexList(&A->data); + break; #endif case ACL_PROTO: aclParseProtoList(&A->data); @@ -725,6 +741,14 @@ assert(proxy_auth_cache); } break; + case ACL_PROXY_AUTH_REGEX: + aclParseRegexList(&A->data); + if (!proxy_auth_cache) { + /* First time around, 7921 should be big enough */ + proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); + assert(proxy_auth_cache); + } + break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: aclParseWordList(&A->data); @@ -996,17 +1020,25 @@ 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, 2) ("aclDecodeProxyAuth: Invalid sheme, '%s'\n", proxy_auth); return 0; - proxy_auth += SKIP_BASIC_SZ; + } + proxy_auth += 6; sent_auth = xstrdup(proxy_auth); /* username and password */ /* Trim trailing \n before decoding */ strtok(sent_auth, "\n"); /* Trim leading whitespace before decoding */ - while (xisspace(*proxy_auth)) - proxy_auth++; + while (xisspace(*sent_auth)) + sent_auth++; cleartext = uudecode(sent_auth); xfree(sent_auth); + /* + * Don't allow NL or CR in the credentials. + * Oezguer Kesim + */ + strtok(cleartext, "\r\n"); debug(28, 6) ("aclDecodeProxyAuth: cleartext = '%s'\n", cleartext); xstrncpy(buf, cleartext, bufsize); xfree(cleartext); @@ -1014,7 +1046,7 @@ 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; } return 1; @@ -1029,7 +1061,7 @@ */ static int -aclMatchProxyAuth(wordlist * data, const char *proxy_auth, acl_proxy_auth_user * auth_user, aclCheck_t * checklist) +aclMatchProxyAuth(void * data, const char *proxy_auth, acl_proxy_auth_user * auth_user, aclCheck_t * checklist, squid_acl acltype) { /* checklist is used to register user name when identified, nothing else */ LOCAL_ARRAY(char, login_buf, USER_IDENT_SZ); @@ -1067,6 +1099,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 = current_time.tv_sec + Config.authenticateIpTTL; + auth_user->ipaddr = checklist->src_addr; hash_join(proxy_auth_cache, (hash_link *) auth_user); /* Continue checking below, as normal */ } @@ -1080,12 +1114,33 @@ 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 <= 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); + auth_user->ip_expiretime = current_time.tv_sec + Config.authenticateIpTTL; + auth_user->ipaddr = checklist->src_addr; + switch(acltype) { + case ACL_PROXY_AUTH: + return aclMatchUser(data, user); + case ACL_PROXY_AUTH_REGEX: + return aclMatchRegex(data, user); + default: + fatal("aclMatchProxyAuth: unknown ACL type"); + return 0; /* NOTREACHED */ + } + } 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", @@ -1332,6 +1387,9 @@ case ACL_URL_PORT: return aclMatchIntegerRange(ae->data, r->port); /* NOTREACHED */ + case ACL_MY_PORT: + return aclMatchIntegerRange(ae->data, checklist->my_port); + /* NOTREACHED */ #if USE_IDENT case ACL_IDENT: if (checklist->ident[0]) { @@ -1341,6 +1399,14 @@ return 0; } /* NOTREACHED */ + case ACL_IDENT_REGEX: + if (checklist->ident[0]) { + return aclMatchRegex(ae->data, checklist->ident); + } else { + checklist->state[ACL_IDENT] = ACL_LOOKUP_NEEDED; + return 0; + } + /* NOTREACHED */ #endif case ACL_PROTO: return aclMatchInteger(ae->data, r->protocol); @@ -1352,6 +1418,7 @@ return aclMatchRegex(ae->data, checklist->browser); /* NOTREACHED */ case ACL_PROXY_AUTH: + case ACL_PROXY_AUTH_REGEX: if (NULL == r) { return -1; } else if (!r->flags.accelerated) { @@ -1381,7 +1448,8 @@ switch (aclMatchProxyAuth(ae->data, header, checklist->auth_user, - checklist)) { + checklist, + ae->type)) { case 0: /* Correct password, but was not allowed in this ACL */ return 0; @@ -1675,8 +1743,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) { @@ -1689,10 +1755,12 @@ * 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) @@ -1792,6 +1860,10 @@ case ACL_TIME: aclDestroyTimeList(a->data); break; +#if USE_IDENT + case ACL_IDENT_REGEX: +#endif + case ACL_PROXY_AUTH_REGEX: case ACL_URL_REGEX: case ACL_URLPATH_REGEX: case ACL_BROWSER: @@ -1809,6 +1881,9 @@ case ACL_URL_PORT: aclDestroyIntRange(a->data); break; + case ACL_MY_PORT: + aclDestroyIntRange(a->data); + break; case ACL_NONE: default: debug(28, 1) ("aclDestroyAcls: no case for ACL type %d\n", a->type); @@ -1886,67 +1961,35 @@ /* 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; - int l1; - int l2; - while ('.' == *d1) - d1++; - while ('.' == *d2) - d2++; - l1 = strlen(d1); - l2 = strlen(d2); - while (d1[--l1] == d2[--l2]) { - if ((l1 == 0) && (l2 == 0)) - return 0; /* d1 == d2 */ - if (0 == l1) { - if ('.' == d2[l2 - 1]) { - debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d2, d1); - debug(28, 0) ("WARNING: This may break Splay tree searching\n"); - debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d2, AclMatchedName); - } - return -1; /* d1 < d2 */ - } - if (0 == l2) { - if ('.' == d1[l1 - 1]) { - debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d1, d2); - debug(28, 0) ("WARNING: This may break Splay tree searching\n"); - debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d1, AclMatchedName); - } - return 1; /* d1 > d2 */ - } + const char *d1; + const char *d2; + int ret; + d1=b; + d2=a; + ret = aclHostDomainCompare(d1, d2); + if (ret != 0) { + d1=a; + d2=b; + ret = aclHostDomainCompare(d1, d2); + } + if (ret == 0) { + debug(28,0 ) ("WARNING: '%s' is a subdomain of '%s'\n", d1, d2); + debug(28, 0) ("WARNING: because of this '%s' is ignored to keep splay tree searching predictable\n", a); + debug(28, 0) ("WARNING: You should probably remove '%s' from the ACL named '%s'\n", d1, AclMatchedName); } - return (d1[l1] - d2[l2]); + return ret; } /* 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 +2006,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 */ @@ -2154,6 +2197,9 @@ case ACL_URL_PORT: return aclDumpIntRangeList(a->data); break; + case ACL_MY_PORT: + return aclDumpIntRangeList(a->data); + break; case ACL_PROTO: return aclDumpProtoList(a->data); break; @@ -2305,10 +2351,10 @@ } 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 +2433,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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/aiops.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/aiops.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 43 AIOPS * AUTHOR: Stewart Forster @@ -46,11 +46,18 @@ #include #endif -#ifndef NUMTHREADS -#define NUMTHREADS 16 +#ifndef NR_ASYNC_IO_THREADS +#define NR_ASYNC_IO_THREADS 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 AIO_PROPER_MUTEX 1 +#endif + enum _aio_thread_status { _THREAD_STARTING = 0, _THREAD_WAITING, @@ -110,6 +117,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 *); @@ -168,9 +176,9 @@ #endif /* Create threads and get them to sit in their wait loop */ - threads = xcalloc(NUMTHREADS, sizeof(aio_thread_t)); + threads = xcalloc(NR_ASYNC_IO_THREADS, sizeof(aio_thread_t)); - for (i = 0; i < NUMTHREADS; i++) { + for (i = 0; i < NR_ASYNC_IO_THREADS; i++) { threadp = &threads[i]; threadp->status = _THREAD_STARTING; if (pthread_mutex_init(&(threadp->mutex), NULL)) { @@ -333,7 +341,7 @@ /* Kick it rolling */ aio_process_request_queue(); /* Warn if out of threads */ - if (request_queue_len > (NUMTHREADS >> 1)) { + if (request_queue_len > (NR_ASYNC_IO_THREADS >> 1)) { if (high_start == 0) { high_start = squid_curtime; queue_high = request_queue_len; @@ -344,15 +352,15 @@ 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"); + debug(43, 1) ("aio_queue_request: Perhaps you should increase NR_ASYNC_IO_THREADS\n"); debug(43, 1) ("aio_queue_request: Or install more disks to share the load\n"); - debug(43, 3) ("aio_queue_request: First %d items on request queue\n", NUMTHREADS); + debug(43, 3) ("aio_queue_request: First %d items on request queue\n", NR_ASYNC_IO_THREADS); rp = request_queue_head; - for (i = 1; i <= NUMTHREADS; i++) { + for (i = 1; i <= NR_ASYNC_IO_THREADS; i++) { switch (rp->request_type) { case _AIO_OP_OPEN: debug(43, 3) ("aio_queue_request: %d : open -> %s\n", i, rp->path); @@ -386,8 +394,9 @@ } 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 */ @@ -838,13 +847,38 @@ 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) +{ + do { + aio_poll_threads(); + } while(request_queue_len > 0 || busy_threads_head != NULL ); + 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/asn.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/asn.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/async_io.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/async_io.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 32 Asynchronous Disk I/O * AUTHOR: Pete Bentley @@ -367,6 +367,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,7 +380,7 @@ 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"); } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/authenticate.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/authenticate.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -37,6 +37,8 @@ typedef struct { void *data; + char user[256]; + char passwd[256]; acl_proxy_auth_user *auth_user; RH *handler; } authenticateStateData; @@ -96,11 +98,13 @@ } r = xcalloc(1, sizeof(authenticateStateData)); cbdataAdd(r, cbdataXfree, 0); + xstrncpy(r->user, rfc1738_escape(auth_user->user), sizeof(r->user)); + xstrncpy(r->passwd, rfc1738_escape(auth_user->passwd), sizeof(r->passwd)); r->handler = handler; cbdataLock(data); r->data = data; r->auth_user = auth_user; - snprintf(buf, 8192, "%s %s\n", r->auth_user->user, r->auth_user->passwd); + snprintf(buf, 8192, "%s %s\n", r->user, r->passwd); helperSubmit(authenticators, buf, authenticateHandleReply, r); } @@ -114,7 +118,7 @@ authenticators = helperCreate("authenticator"); authenticators->cmdline = Config.Program.authenticate; authenticators->n_to_start = Config.authenticateChildren; - authenticators->ipc_type = IPC_TCP_SOCKET; + authenticators->ipc_type = IPC_STREAM; helperOpenServers(authenticators); if (!init) { cachemgrRegister("authenticator", 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/cache_cf.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/cache_cf.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -277,7 +277,7 @@ fatal("No http_port specified!"); snprintf(ThisCache, sizeof(ThisCache), "%s:%d (%s)", uniqueHostname(), - (int) Config.Port.http->i, + (int) Config.Port.http->port, full_appname_string); /* * the extra space is for loop detection in client_side.c -- we search @@ -285,7 +285,7 @@ */ snprintf(ThisCache2, sizeof(ThisCache), " %s:%d (%s)", uniqueHostname(), - (int) Config.Port.http->i, + (int) Config.Port.http->port, full_appname_string); if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF) Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF; @@ -527,6 +527,62 @@ memset(addr, '\0', sizeof(struct in_addr)); } +static int +check_null_ipportlist(ipportlist * u) +{ + return u == NULL; +} + +static void +dump_ipportlist(StoreEntry * entry, const char *name, ipportlist * ip) +{ + while (ip) { + storeAppendPrintf(entry, "%s %s:%d\n", name, inet_ntoa(ip->addr), + (int) ip->port); + ip = ip->next; + } +} + +static void +parse_ipportlist(ipportlist **portlist) +{ + const struct hostent *hp; + char *token, *port; + ipportlist *ipport; + while (*portlist) + portlist = &(*portlist)->next; + while ((token = strtok(NULL, w_space)) != NULL) { + ipport = xcalloc(1, sizeof(*ipport)); + port = strchr(token, ':'); + if (port) { + *port++ = '\0'; + if (safe_inet_addr(token, &ipport->addr) == 1) + (void) 0; + else if ((hp = gethostbyname(token))) /* dont use ipcache */ + ipport->addr = inaddrFromHostent(hp); + else + self_destruct(); + } else { + port = token; + ipport->addr.s_addr = INADDR_ANY; + } + if (sscanf(port, "%hu", &ipport->port) != 1) + self_destruct(); + *portlist = ipport; + portlist = &(*portlist)->next; + } +} + +static void +free_ipportlist(ipportlist ** P) +{ + ipportlist *ip; + while ((ip = *P) != NULL) { + *P = ip->next; + xfree(ip); + } +} + #if DELAY_POOLS /* do nothing - free_delay_pool_count is the magic free function. @@ -923,7 +979,7 @@ char *token = NULL; peer *p; int i; - ushortlist *u; + ipportlist *u; const char *me = null_string; /* XXX */ p = memAllocate(MEM_PEER); p->http_port = CACHE_HTTP_PORT; @@ -942,7 +998,7 @@ 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) + if (p->http_port != u->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 +1047,10 @@ #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); + } else if (!strcasecmp(token, "allow-miss")) { + p->options.allow_miss = 1; } else { debug(3, 0) ("parse_peer: token='%s'\n", token); self_destruct(); @@ -1000,6 +1060,7 @@ p->weight = 1; p->icp.version = ICP_VERSION_CURRENT; p->tcp_up = PEER_TCP_MAGIC_COUNT; + p->test_fd = -1; #if USE_CARP if (p->carp.load_factor) { /* calculate this peers hash for use in CARP */ @@ -1190,6 +1251,7 @@ } } +#if UNUSED static void dump_ushortlist(StoreEntry * entry, const char *name, ushortlist * u) { @@ -1233,6 +1295,7 @@ xfree(u); } } +#endif static void dump_int(StoreEntry * entry, const char *name, int var) 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/cf.data.pre 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/cf.data.pre 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ # # # SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -54,7 +54,7 @@ COMMENT_END NAME: http_port ascii_port -TYPE: ushortlist +TYPE: ipportlist DEFAULT: none DEFAULT_IF_NONE: 3128 LOC: Config.Port.http @@ -66,6 +66,10 @@ You may specify multiple ports here, but they MUST all be on a single line. + Each port number can be prefixed with an ipaddress to specify + which network interface Squid should listen on, using ipaddress:port + syntax. + http_port 3128 DOC_END @@ -224,6 +228,8 @@ no-netdb-exchange no-delay login=user:password + connect-timeout=nn + allow-miss use 'proxy-only' to specify that objects fetched from this cache should not be saved locally. @@ -272,6 +278,16 @@ 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 (see also peer_connect_timeout directive) + + use 'allow-miss' to disable Squid's use of only-if-cached + when forwarding requests to siblings. This is primarily + useful when icp_hit_stale is used by the sibling. To + extensive use of this option may result in forwarding + loops, and you should avoid having two-way peerings + with this option. + NOTE: non-ICP neighbors must be specified as 'parent'. cache_peer hostname type 3128 3130 @@ -648,14 +664,19 @@ DOC_START Location for the cache "swap.log." This log file holds the metadata of objects saved on disk. It is used to rebuild the - cache during startup. Normally this file resides in the first + cache during startup. Normally this file resides in each 'cache_dir' directory, but you may specify an alternate pathname here. Note you must give a full filename, not just a directory. Since this is the index for the whole object list you CANNOT periodically rotate it! - If you have more than one 'cache_dir', these swap logs will - have names such as: + If %s can be used in the file name then it will be replaced with a + a representation of the cache_dir name where each / is replaced + with '.'. This is needed to allow adding/removing cache_dir + lines when cache_swap_log is being used. + + If have more than one 'cache_dir', and %s is not used in the name + then these swap logs will have names such as: cache_swap_log.00 cache_swap_log.01 @@ -851,6 +872,18 @@ dns_children 5 DOC_END +NAME: dns_restart +TYPE: int +DEFAULT: 0 +LOC: Config.dnsRestart +DOC_START + dnsserver (or perhaps the resolver library) seems to be leaking + memory. This option can be used to make the dnsserver slave processes + restart every now and then (restarts after N requests). + The default is 0 to disable restarts. + +dns_restart 0 +DOC_END NAME: dns_defnames COMMENT: on|off @@ -998,6 +1031,26 @@ authenticate_ttl 3600 DOC_END +NAME: authenticate_ip_ttl +TYPE: int +LOC: Config.authenticateIpTTL +DEFAULT: 0 +DOC_START + Whith 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 ----------------------------------------------------------------------------- @@ -1086,9 +1139,11 @@ 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 @@ -1106,7 +1161,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 @@ -1250,6 +1305,21 @@ 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 the connect to a + peer cache to complete. The default is 30 seconds. The reason + to this is to speed up recovery when a peer cache fails. See also + connect-timeout cache_peer option for an per peer specific way + to specify this. + +peer_connect_timeout 30 seconds +DOC_END + NAME: siteselect_timeout COMMENT: time-units TYPE: time_t @@ -1280,13 +1350,14 @@ NAME: request_timeout TYPE: time_t LOC: Config.Timeout.request -DEFAULT: 30 seconds +DEFAULT: 5 minutes DOC_START - How long to wait for an HTTP request after connection - establishment. For persistent connections, wait this long - after the previous request completes. + How long to wait for the first HTTP request after connection + establishment. + + For persistent connections idle timeout, see pconn_timeout. -request_timeout 30 seconds +request_timeout 5 minutes DOC_END @@ -1336,8 +1407,12 @@ LOC: Config.Timeout.pconn DEFAULT: 120 seconds DOC_START - Timeout for idle persistent connections to servers and other - proxies. + Timeout for idle persistent connections to clients, servers + and other proxies. + + Persistent connections will be disabled if this is less than 10 + seconds. + pconn_timeout 120 seconds DOC_END @@ -1423,11 +1498,13 @@ 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 IP port) acl aclname proto HTTP FTP ... acl aclname method GET POST ... acl aclname browser [-i] regexp # pattern match on User-Agent header acl aclname ident username ... + acl aclname ident_regex [-i] pattern ... # string match on ident output. # use REQUIRED to accept any non-null ident. acl aclname src_as number ... @@ -1441,6 +1518,7 @@ # cache_peer_access mycache_mydomain.net deny all acl aclname proxy_auth username ... + acl aclname proxy_auth_regex [-i] pattern ... # list of valid usernames # use REQUIRED to accept any valid username. # @@ -2412,7 +2490,7 @@ 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. @@ -2776,19 +2854,42 @@ encrypted. This is the encryption key. DOC_END +NAME: nonhierarchical_direct +TYPE: onoff +LOC: Config.onoff.nonhierarchical_direct +DEFAULT: on +DOC_START + By default, Squid will send any non-hierarchical requests + (matching hierarchy_stoplist or not cachable request type) direct + to origin servers. + + If you set this to off, then Squid will prefer to send these + requests to parents. + + Note that in most configurations, by turning this off you will only + add latency to these request without any improvement in global hit + ratio. + + If you are inside an firewall then see never_direct instead of + this directive. + +nonhierarchical_direct on +DOC_END + NAME: prefer_direct TYPE: onoff LOC: Config.onoff.prefer_direct -DEFAULT: on +DEFAULT: off DOC_START - By default, if the ICP, HTCP, Cache Digest, etc. techniques - do not yield a parent cache, Squid gives higher preference - to forwarding the request direct to origin servers, rather - than selecting a parent cache anyway. - - If you want Squid to give higher precedence to a parent - cache, instead of going direct, then turn this option off. -prefer_direct on + Normally Squid tries to use parents for most requests. If you by some + reason like it to first try going direct and only use a parent if + going direct fails then set this to off. + + By combining nonhierarchical_direct off and prefer_direct on you + can set up Squid to use a parent as a backup path if going direct + fails. + +prefer_direct off DOC_END NAME: strip_query_terms @@ -2812,4 +2913,14 @@ and coredump files will be left there. 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 privilegies after initializing + (with the side effect that HTTP connections using low port numbers + can't be reopened after a reconfigure) +DOC_END EOF 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/client_side.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/client_side.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -144,8 +144,6 @@ 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 @@ -277,6 +275,7 @@ 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); @@ -326,13 +325,12 @@ /* 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"); @@ -538,6 +536,8 @@ return; } http->log_type = LOG_TCP_MISS; + /* Release both IP and object cache entries */ + ipcacheInvalidate(http->request->host); if ((entry = storeGetPublic(http->uri, METHOD_GET)) == NULL) { http->http_code = HTTP_NOT_FOUND; } else { @@ -856,12 +856,21 @@ static int clientCheckContentLength(request_t * r) { - /* We only require a content-length for "upload" methods */ - if (!pumpMethod(r->method)) + int has_cont_len = (httpHeaderGetInt(&r->header, HDR_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 +891,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 */ @@ -1001,7 +1012,9 @@ { HttpHeader *hdr = rep ? &rep->header : 0; const char *range_err = NULL; - assert(http->request->range); + request_t *request = http->request; + int is_hit = isTcpHit(http->log_type); + assert(request->range); /* check if we still want to do ranges */ if (!rep) range_err = "no [parse-able] reply"; @@ -1019,6 +1032,11 @@ range_err = "canonization failed"; else if (httpHdrRangeIsComplex(http->request->range)) range_err = "too complex range header"; + else if (!request->flags.cachable) /* from we_do_ranges in http.c */ + range_err = "non-cachable request"; + else if (!is_hit && Config.rangeOffsetLimit < httpHdrRangeFirstOffset(request->range) + && Config.rangeOffsetLimit != -1) /* from we_do_ranges in http.c */ + range_err = "range outside range_offset_limit"; /* get rid of our range specs on error */ if (range_err) { debug(33, 2) ("clientBuildRangeHeader: will not do ranges: %s.\n", range_err); @@ -1105,20 +1123,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 +1154,16 @@ /* 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(), Config.Port.http->port); #endif /* - * Clear keepalive for NON-HEAD requests with invalid content length + * Clear keepalive unless there is a valid content length or + * if the reply type only has headers (HEAD or IMS). */ - if (request->method != METHOD_HEAD) - if (http->entry->mem_obj->reply->content_length < 0) - request->flags.proxy_keepalive = 0; + if (http->entry->mem_obj->reply->content_length < 0) + if (request->method != METHOD_HEAD) + if (http->entry->mem_obj->reply->sline.status != HTTP_NOT_MODIFIED) + request->flags.proxy_keepalive = 0; /* Signal keep-alive if needed */ httpHeaderPutStr(hdr, http->flags.accel ? HDR_CONNECTION : HDR_PROXY_CONNECTION, @@ -1155,21 +1184,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 +1345,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); @@ -1591,7 +1624,7 @@ /* * Set the timeout BEFORE calling clientReadRequest(). */ - commSetTimeout(conn->fd, 15, requestTimeout, conn); + commSetTimeout(conn->fd, Config.Timeout.pconn, requestTimeout, conn); clientReadRequest(conn->fd, conn); /* Read next request */ /* * Note, the FD may be closed at this point. @@ -1645,7 +1678,12 @@ } 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 (http->request->flags.proxy_keepalive && ( + http->request->method == METHOD_HEAD || + http->entry->mem_obj->reply->sline.status == HTTP_NOT_MODIFIED)) { + debug(33, 5) ("clientWriteComplete: FD %d Keeping Alive\n", fd); + clientKeepaliveNextRequest(http); + } else if (http->entry->mem_obj->reply->content_length < 0) { debug(33, 5) ("clientWriteComplete: closing, content_length < 0\n"); comm_close(fd); } else if (!done) { @@ -1711,6 +1749,13 @@ /* We can generate a HEAD reply from a cached GET object */ e = http->entry = storeGetPublic(http->uri, METHOD_GET); } + /* Release negatively cached IP-cache entries on reload */ + if (r->flags.nocache) + ipcacheReleaseInvalid(r->host); +#if HTTP_VIOLATIONS + else if (r->flags.nocache_hack) + ipcacheReleaseInvalid(r->host); +#endif #if USE_CACHE_DIGESTS http->lookup_type = e ? "HIT" : "MISS"; #endif @@ -1736,12 +1781,6 @@ return LOG_TCP_HIT; } #if HTTP_VIOLATIONS - if (r->flags.nocache_hack) { - /* if nocache_hack is set, nocache should always be clear, right? */ - assert(!r->flags.nocache); - ipcacheReleaseInvalid(r->host); - /* continue! */ - } if (e->store_status == STORE_PENDING) { if (r->flags.nocache || r->flags.nocache_hack) { debug(33, 3) ("Clearing no-cache for STORE_PENDING request\n\t%s\n", @@ -1806,7 +1845,7 @@ } /* yes, continue */ http->log_type = LOG_TCP_MISS; - } else if (pumpMethod(r->method)) { + } else if (r->body) { http->log_type = LOG_TCP_MISS; /* XXX oof, POST can be cached! */ pumpInit(fd, r, http->uri); @@ -1891,8 +1930,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 +2164,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); @@ -2153,6 +2191,7 @@ int k; request_t *request = NULL; int size; + int cont_len; method_t method; clientHttpRequest *http = NULL; clientHttpRequest **H = NULL; @@ -2169,10 +2208,9 @@ } /* * Don't reset the timeout value here. The timeout value will be - * set to Config.Timeout.request by httpAccept() and - * clientWriteComplete(), and should apply to the request as a - * whole, not individual read() calls. Plus, it breaks our - * lame half-close detection + * set to by httpAccept() and clientWriteComplete(), and should + * apply to the request headers as a whole, not individual read() + * calls. Plus, it breaks our lame half-close detection */ commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, conn, 0); if (size == 0) { @@ -2218,7 +2256,7 @@ break; /* Limit the number of concurrent requests to 2 */ for (H = &conn->chr, nrequests = 0; *H; H = &(*H)->next, nrequests++); - if (nrequests >= 2) { + if (nrequests >= 1) { debug(33, 2) ("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 */ @@ -2279,11 +2317,11 @@ if (!http->flags.internal) { if (internalCheck(strBuf(request->urlpath))) { if (0 == strcasecmp(request->host, internalHostname()) && - request->port == Config.Port.http->i) { + request->port == Config.Port.http->port) { http->flags.internal = 1; } else if (internalStaticCheck(strBuf(request->urlpath))) { xstrncpy(request->host, internalHostname(), SQUIDHOSTNAMELEN); - request->port = Config.Port.http->i; + request->port = Config.Port.http->port; http->flags.internal = 1; } } @@ -2294,6 +2332,7 @@ 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); @@ -2321,22 +2360,18 @@ */ 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. */ - if (request->method != METHOD_GET) { - int cont_len = httpHeaderGetInt(&request->header, HDR_CONTENT_LENGTH); + cont_len = httpHeaderGetInt(&request->header, HDR_CONTENT_LENGTH); + if (cont_len >= 0) { int copy_len = XMIN(conn->in.offset, cont_len); - if (copy_len > 0) { - assert(conn->in.offset >= copy_len); - request->body_sz = copy_len; - request->body = xmalloc(request->body_sz); - xmemcpy(request->body, conn->in.buf, request->body_sz); - conn->in.offset -= copy_len; - if (conn->in.offset) - xmemmove(conn->in.buf, conn->in.buf + copy_len, conn->in.offset); - } + assert(conn->in.offset >= copy_len); + request->body_sz = copy_len; + request->body = xmalloc(request->body_sz); + xmemcpy(request->body, conn->in.buf, request->body_sz); + conn->in.offset -= copy_len; + if (conn->in.offset) + xmemmove(conn->in.buf, conn->in.buf + copy_len, conn->in.offset); /* * if we didn't get the full body now, then more will * be arriving on the client socket. Lets cancel @@ -2475,6 +2510,7 @@ #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 @@ -2611,14 +2647,14 @@ void clientHttpConnectionsOpen(void) { - ushortlist *u; + ipportlist *ip; int fd; - for (u = Config.Port.http; u; u = u->next) { + for (ip = Config.Port.http; ip; ip = ip->next) { enter_suid(); fd = comm_open(SOCK_STREAM, 0, - Config.Addrs.tcp_incoming, - u->i, + ip->addr.s_addr != INADDR_ANY ? ip->addr : Config.Addrs.tcp_incoming, + ip->port, COMM_NONBLOCKING, "HTTP Socket"); leave_suid(); @@ -2627,8 +2663,8 @@ 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 on port %s:%d, FD %d.\n", + inet_ntoa(ip->addr), (int) ip->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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/comm.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/comm.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -39,12 +39,6 @@ #include #endif -#if USE_ASYNC_IO -#define MAX_POLL_TIME 10 -#else -#define MAX_POLL_TIME 1000 -#endif - typedef struct { char *host; u_short port; @@ -311,6 +305,18 @@ fdAdjustReserved(); return 0; } + /* + * yuck, this has assumptions about comm_open() arguments for + * the original socket + */ + if (Config.Addrs.tcp_outgoing.s_addr != no_addr.s_addr) { + if (commBind(fd2, Config.Addrs.tcp_outgoing, 0) != COMM_OK) { + return 0; + } + } + /* + * Move the new socket to the old filedescriptor + */ if (dup2(fd2, cs->fd) < 0) { debug(5, 0) ("commResetFD: dup2: %s\n", xstrerror()); fdAdjustReserved(); @@ -319,15 +325,10 @@ close(fd2); fd_table[cs->fd].flags.called_connect = 0; /* - * yuck, this has assumptions about comm_open() arguments for + * yuck, this has more assumptions about comm_open() arguments for * the original socket */ commSetCloseOnExec(cs->fd); - if (Config.Addrs.tcp_outgoing.s_addr != no_addr.s_addr) { - if (commBind(cs->fd, Config.Addrs.tcp_outgoing, 0) != COMM_OK) { - return 0; - } - } commSetNonBlocking(cs->fd); #ifdef TCP_NODELAY commSetTcpNoDelay(cs->fd); 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/comm_select.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/comm_select.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 5 Socket Functions * @@ -199,15 +199,15 @@ 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 (revents & (POLLRDNORM | POLLIN)) + 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 (revents & (POLLWRNORM | POLLOUT)) + debug(5, 1) ("comm_poll_incoming: fd %d NULL write handler\n", fd); } } return incame; 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/defines.h 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/defines.h 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -193,6 +193,16 @@ #define IPC_TCP_SOCKET 1 #define IPC_UDP_SOCKET 2 #define IPC_FIFO 3 +#define IPC_UNIX_STREAM 4 +#define IPC_UNIX_DGRAM 5 + +#if HAVE_SOCKETPAIR && defined (AF_UNIX) +#define IPC_STREAM IPC_UNIX_STREAM +#define IPC_DGRAM IPC_UNIX_DGRAM +#else +#define IPC_STREAM IPC_TCP_SOCKET +#define IPC_DGRAM IPC_UDP_SOCKET +#endif #define STORE_META_KEY STORE_META_KEY_MD5 @@ -208,8 +218,6 @@ #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 #define COUNT_INTERVAL 60 @@ -269,4 +277,4 @@ #define _PATH_DEVNULL "/dev/null" #endif -#define USE_TRUNCATE_NOT_UNLINK 1 +#define USE_TRUNCATE_NOT_UNLINK 0 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/delay_pools.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/delay_pools.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: David Luyer @@ -217,18 +217,18 @@ */ switch (class) { case 1: - delay_data[pool].class1->aggregate = (rates->aggregate.max_bytes * - Config.Delay.initial) / 100; + delay_data[pool].class1->aggregate = (int)(((double)rates->aggregate.max_bytes * + Config.Delay.initial) / 100); break; case 2: - delay_data[pool].class2->aggregate = (rates->aggregate.max_bytes * - Config.Delay.initial) / 100; + delay_data[pool].class2->aggregate = (int)(((double)rates->aggregate.max_bytes * + Config.Delay.initial) / 100); delay_data[pool].class2->individual_map[0] = 255; delay_data[pool].class2->individual_255_used = 0; break; case 3: - delay_data[pool].class3->aggregate = (rates->aggregate.max_bytes * - Config.Delay.initial) / 100; + delay_data[pool].class3->aggregate = (int)(((double)rates->aggregate.max_bytes * + Config.Delay.initial) / 100); delay_data[pool].class3->network_map[0] = 255; delay_data[pool].class3->network_255_used = 0; memset(&delay_data[pool].class3->individual_255_used, '\0', @@ -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)) @@ -301,8 +302,8 @@ if (!delay_data[pool].class2->individual_255_used) { delay_data[pool].class2->individual_255_used = 1; delay_data[pool].class2->individual[255] = - (Config.Delay.rates[pool]->individual.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->individual.max_bytes * + Config.Delay.initial) / 100); } return delayId(pool + 1, 255); } @@ -313,8 +314,8 @@ delay_data[pool].class2->individual_map[i] = host; delay_data[pool].class2->individual_map[i + 1] = 255; delay_data[pool].class2->individual[i] = - (Config.Delay.rates[pool]->individual.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->individual.max_bytes * + Config.Delay.initial) / 100); break; } } @@ -329,8 +330,8 @@ if (!delay_data[pool].class3->network_255_used) { delay_data[pool].class3->network_255_used = 1; delay_data[pool].class3->network[255] = - (Config.Delay.rates[pool]->network.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->network.max_bytes * + Config.Delay.initial) / 100); } } else { for (i = 0;; i++) { @@ -341,8 +342,8 @@ delay_data[pool].class3->individual_map[i][0] = 255; delay_data[pool].class3->network_map[i + 1] = 255; delay_data[pool].class3->network[i] = - (Config.Delay.rates[pool]->network.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->network.max_bytes * + Config.Delay.initial) / 100); break; } } @@ -353,8 +354,8 @@ if (!(delay_data[pool].class3->individual_255_used[i / 8] & (1 << (i % 8)))) { delay_data[pool].class3->individual_255_used[i / 8] |= (1 << (i % 8)); delay_data[pool].class3->individual[position] = - (Config.Delay.rates[pool]->individual.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->individual.max_bytes * + Config.Delay.initial) / 100); } return delayId(pool + 1, position); } @@ -367,8 +368,8 @@ delay_data[pool].class3->individual_map[i][j] = host; delay_data[pool].class3->individual_map[i][j + 1] = 255; delay_data[pool].class3->individual[position |= j] = - (Config.Delay.rates[pool]->individual.max_bytes * - Config.Delay.initial) / 100; + (int)(((double)Config.Delay.rates[pool]->individual.max_bytes * + Config.Delay.initial) / 100); break; } } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/disk.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/disk.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -1,7 +1,7 @@ /* - * $Id: disk.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $ + * $Id: disk.c,v 1.1.1.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 6 Disk I/O Routines * AUTHOR: Harvest Derived @@ -76,7 +76,7 @@ /* Open file */ Opening_FD++; -#if USE_ASYNC_IO +#if USE_ASYNC_IO_OPEN if (callback != NULL) { aioOpen(path, mode, 0644, fileOpenComplete, ctrlp, tag); return DISK_OK; @@ -131,14 +131,7 @@ { 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 assert(fd >= 0); -#endif assert(F->flags.open); if ((callback = F->read_handler)) { F->read_handler = NULL; @@ -164,7 +157,7 @@ */ assert(F->write_handler == NULL); F->flags.closing = 1; -#if USE_ASYNC_IO +#if USE_ASYNC_IO_CLOSE aioClose(fd); #else #if CALL_FSYNC_BEFORE_CLOSE @@ -174,7 +167,7 @@ #endif debug(6, F->flags.close_request ? 2 : 5) ("file_close: FD %d, really closing\n", fd); -#if !USE_ASYNC_IO +#if !USE_ASYNC_IO_CLOSE fd_close(fd); #endif Counter.syscalls.disk.closes++; @@ -230,7 +223,7 @@ static void diskHandleWrite(int fd, void *notused) { -#if !USE_ASYNC_IO +#if !USE_ASYNC_IO_WRITE int len = 0; #endif fde *F = &fd_table[fd]; @@ -243,7 +236,7 @@ debug(6, 3) ("diskHandleWrite: FD %d\n", fd); assert(fdd->write_q != NULL); assert(fdd->write_q->len > fdd->write_q->buf_offset); -#if USE_ASYNC_IO +#if USE_ASYNC_IO_WRITE aioWrite(fd, -1, /* seek offset, -1 == append */ fdd->write_q->buf + fdd->write_q->buf_offset, @@ -434,21 +427,19 @@ } if (!F->flags.write_daemon) { cbdataLock(F->disk.wrt_handle_data); -#if USE_ASYNC_IO +#if USE_ASYNC_IO_WRITE diskHandleWrite(fd, NULL); #else #ifdef OPTIMISTIC_IO - if (F->flags.calling_io_handler) + if (F->flags.calling_io_handler) { #endif commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); + F->flags.write_daemon = 1; #ifdef OPTIMISTIC_IO - else + } else diskHandleWrite(fd, NULL); #endif #endif -#ifndef OPTIMISTIC_IO - F->flags.write_daemon = 1; -#endif } } @@ -467,7 +458,7 @@ diskHandleRead(int fd, void *data) { dread_ctrl *ctrl_dat = data; -#if !USE_ASYNC_IO +#if !USE_ASYNC_IO_READ fde *F = &fd_table[fd]; int len; #endif @@ -482,7 +473,7 @@ memFree(ctrl_dat, MEM_DREAD_CTRL); return; } -#if USE_ASYNC_IO +#if USE_ASYNC_IO_READ aioRead(fd, ctrl_dat->offset, ctrl_dat->buf, @@ -566,7 +557,7 @@ ctrl_dat->handler = handler; ctrl_dat->client_data = client_data; cbdataLock(client_data); -#if USE_ASYNC_IO +#if USE_ASYNC_IO_READ diskHandleRead(fd, ctrl_dat); #else #ifndef OPTIMISTIC_IO 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/dns.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/dns.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -48,13 +48,14 @@ dnsInit(void) { static int init = 0; + static char restart_freq[256]; wordlist *w; if (!Config.Program.dnsserver) return; if (dnsservers == NULL) dnsservers = helperCreate("dnsserver"); dnsservers->n_to_start = Config.dnsChildren; - dnsservers->ipc_type = IPC_TCP_SOCKET; + dnsservers->ipc_type = IPC_STREAM; assert(dnsservers->cmdline == NULL); wordlistAdd(&dnsservers->cmdline, Config.Program.dnsserver); if (Config.onoff.res_defnames) @@ -63,6 +64,11 @@ wordlistAdd(&dnsservers->cmdline, "-s"); wordlistAdd(&dnsservers->cmdline, w->key); } + if (Config.dnsRestart) { + wordlistAdd(&dnsservers->cmdline, "-n"); + snprintf(restart_freq, 256, "%d", Config.dnsRestart); + wordlistAdd(&dnsservers->cmdline, restart_freq); + } helperOpenServers(dnsservers); if (!init) { cachemgrRegister("dns", 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/dnsserver.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/dnsserver.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 0 DNS Resolver * AUTHOR: Harvest Derived @@ -260,6 +260,8 @@ char *t = NULL; int c; int opt_s = 0; + int req_num = 0; + int max_req = 0; extern char *optarg; safe_inet_addr("255.255.255.255", &no_addr); @@ -274,7 +276,7 @@ #endif #endif - while ((c = getopt(argc, argv, "Dhs:v")) != -1) { + while ((c = getopt(argc, argv, "Dhs:vn:")) != -1) { switch (c) { case 'D': #ifdef RES_DEFNAMES @@ -322,6 +324,9 @@ printf("dnsserver version %s\n", SQUID_VERSION); exit(0); break; + case 'n': + max_req = atoi(optarg); + break; case 'h': default: usage(); @@ -330,7 +335,7 @@ } } - for (;;) { + for (req_num = 0 ; req_num < max_req || max_req == 0; req_num++) { memset(request, '\0', REQ_SZ); if (fgets(request, REQ_SZ, stdin) == NULL) exit(1); @@ -343,6 +348,7 @@ lookup(request); fflush(stdout); } - /* NOTREACHED */ - return 0; + execv(argv[0], argv); + /* NOT REACHED */ + return(-1); } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/enums.h 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/enums.h 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -101,13 +101,16 @@ ACL_URLPATH_REGEX, ACL_URL_REGEX, ACL_URL_PORT, + ACL_MY_PORT, #if USE_IDENT ACL_IDENT, + ACL_IDENT_REGEX, #endif ACL_PROTO, ACL_METHOD, ACL_BROWSER, ACL_PROXY_AUTH, + ACL_PROXY_AUTH_REGEX, ACL_SRC_ASN, ACL_DST_ASN, ACL_SRC_ARP, @@ -289,7 +292,8 @@ SOURCE_FASTEST, ROUNDROBIN_PARENT, #if USE_CACHE_DIGESTS - CACHE_DIGEST_HIT, + CD_PARENT_HIT, + CD_SIBLING_HIT, #endif #if USE_CARP CARP, @@ -364,6 +368,15 @@ METHOD_CONNECT, /* 101 */ METHOD_TRACE, /* 110 */ METHOD_PURGE, /* 111 */ + METHOD_OPTIONS, /* HTTP/1.1 9.2 */ + METHOD_DELETE, /* HTTP/1.1 9.7 */ + METHOD_PROPFIND, /* rfc2518 8.1 */ + METHOD_PROPATCH, /* rfc2518 8.2 */ + METHOD_MKCOL, /* rfc2518 8.3 */ + METHOD_COPY, /* rfc2518 8.8 */ + METHOD_MOVE, /* rfc2518 8.9 */ + METHOD_LOCK, /* rfc2518 8.10 */ + METHOD_UNLOCK, /* rfc2518 8.11 */ 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 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 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 = 433, /* RFC2518 10.3 */ + HTTP_LOCKED = 424, /* RFC2518 10.4 */ + HTTP_FAILED_DEPENDENCY = 424, /* RFC2518 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 10.6 */ HTTP_INVALID_HEADER = 600 /* Squid header parsing error */ } http_status; 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/errorpage.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/errorpage.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/event.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/event.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $ * * DEBUG: section 41 Event Processing * AUTHOR: Henrik Nordstrom @@ -125,7 +125,7 @@ break; if (event->id == run_id) /* was added during this run */ break; - if (weight) + if (weight > 3) break; func = event->func; arg = event->arg; @@ -137,7 +137,7 @@ cbdataUnlock(arg); if (!valid) { safe_free(event); - return; + continue; } } weight += event->weight; @@ -167,12 +167,14 @@ eventDump(StoreEntry * sentry) { struct ev_entry *e = tasks; - storeAppendPrintf(sentry, "%s\t%s\n", + storeAppendPrintf(sentry, "%s\t%s\t%s\t%s\n", "Operation", - "Next Execution"); + "Next Execution", + "Weight", + "Id"); 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%d\n", + e->name, e->when - current_dtime, e->weight, e->id); e = e->next; } } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/forward.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/forward.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 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->body) if (0 == pumpRestart(fwdState->request)) return 0; return 1; @@ -130,13 +130,20 @@ fwdState->n_tries, (int) (squid_curtime - fwdState->start)); if (fwdState->servers->next) { - /* cycle */ + /* use next, or cycle if origin server isn't last */ FwdServer *fs = fwdState->servers; - FwdServer **T; + FwdServer **T, *T2 = NULL; fwdState->servers = fs->next; - for (T = &fwdState->servers; *T; T = &(*T)->next); - *T = fs; - fs->next = NULL; + for (T = &fwdState->servers; *T; T2=*T, T = &(*T)->next); + if (T2 && T2->peer) { + /* cycle */ + *T = fs; + fs->next = NULL; + } else { + /* Use next. The last "direct" entry is retried multiple times */ + fwdState->servers = fs->next; + fwdServerFree(fs); + } } /* use eventAdd to break potential call sequence loops */ eventAdd("fwdConnectStart", fwdConnectStart, fwdState, 0.0, 1); @@ -179,12 +186,18 @@ err->request = requestLink(request); fwdFail(fwdState, err); if (fs->peer) - peerCheckConnectStart(fs->peer); + peerConnectFailed(fs->peer); comm_close(server_fd); } else { debug(17, 3) ("fwdConnectDone: FD %d: '%s'\n", server_fd, storeUrl(fwdState->entry)); + if (fs->peer) + hierarchyNote(&fwdState->request->hier, fs->code, fs->peer->host); + else + hierarchyNote(&fwdState->request->hier, fs->code, fd_table[server_fd].ipaddr); fd_note(server_fd, storeUrl(fwdState->entry)); fd_table[server_fd].uses++; + if (fs->peer) + peerConnectSucceded(fs->peer); fwdDispatch(fwdState); } current = NULL; @@ -203,6 +216,8 @@ err->request = requestLink(fwdState->request); err->xerrno = ETIMEDOUT; fwdFail(fwdState, err); + if (fwdState->servers->peer) + peerConnectFailed(fwdState->servers->peer); } comm_close(fd); } @@ -210,6 +225,7 @@ static void fwdConnectStart(void *data) { + time_t timeout = Config.Timeout.connect; FwdState *fwdState = data; const char *url = storeUrl(fwdState->entry); int fd; @@ -223,11 +239,13 @@ if (fs->peer) { host = fs->peer->host; port = fs->peer->http_port; + timeout = Config.Timeout.peer_connect; + if (fs->peer->connect_timeout != 0) + timeout = fs->peer->connect_timeout; } else { host = fwdState->request->host; port = fwdState->request->port; } - hierarchyNote(&fwdState->request->hier, fs->code, host); if ((fd = pconnPop(host, port)) >= 0) { debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd); fwdState->server_fd = fd; @@ -255,7 +273,7 @@ fwdState->n_tries++; comm_add_close_handler(fd, fwdServerClosed, fwdState); commSetTimeout(fd, - Config.Timeout.connect, + timeout, fwdConnectTimeout, fwdState); commConnectStart(fd, host, port, fwdConnectDone, fwdState); @@ -309,6 +327,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) { @@ -357,7 +376,7 @@ } if (fwdState->n_tries > 9) return 0; - if (pumpMethod(fwdState->request->method)) + if (fwdState->request->body) 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; } 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.2.2.1 diff -u -r1.1.1.2 -r1.1.1.2.2.1 --- squid/src/ftp.c 26 Jan 2000 03:23:10 -0000 1.1.1.2 +++ squid/src/ftp.c 4 Feb 2000 16:41:12 -0000 1.1.1.2.2.1 @@ -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.2.2.1 2000/02/04 16:41:12 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,6 +165,8 @@ static void ftpScheduleReadControlReply(FtpStateData *, int); static void ftpHandleControlReply(FtpStateData *); static char *ftpHtmlifyListEntry(char *line, FtpStateData * ftpState); +static void ftpFailed(FtpStateData *, err_type /* ERR_NONE if unknown */); +static void ftpFailedErrorMessage(FtpStateData *, err_type /* ERR_NONE if unknown */); /* State machine functions * send == state transition @@ -234,24 +238,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 +298,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 +318,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,17 +336,13 @@ 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 (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"); } - if (ftpState->data.fd > -1) { - comm_close(ftpState->data.fd); - ftpState->data.fd = -1; - } - comm_close(ftpState->ctrl.fd); + ftpFailed(ftpState, ERR_READ_TIMEOUT); /* don't modify ftpState here, it has been freed */ } @@ -361,7 +363,7 @@ storeAppendPrintf(e, "\n"); if (ftpState->flags.use_base) storeAppendPrintf(e, "\n", - ftpState->title_url); + ftpState->base_href); storeAppendPrintf(e, "\n"); if (ftpState->cwd_message) { storeAppendPrintf(e, "
\n");
@@ -697,7 +699,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':
@@ -838,13 +840,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);
 }
@@ -895,7 +890,7 @@
 	ftpListingStart(ftpState);
     }
     if (len < 0) {
-	debug(50, 1) ("ftpDataRead: read error: %s\n", xstrerror());
+	debug(50, ignoreErrno(errno) ? 3 : 1) ("ftpDataRead: read error: %s\n", xstrerror());
 	if (ignoreErrno(errno)) {
 	    commSetSelect(fd,
 		COMM_SELECT_READ,
@@ -903,8 +898,8 @@
 		data,
 		Config.Timeout.read);
 	} else {
-	    assert(mem->inmem_hi > 0);
-	    ftpDataTransferDone(ftpState);
+	    ftpFailed(ftpState, ERR_READ_ERROR);
+	    return;
 	}
     } else if (len == 0) {
 	ftpReadComplete(ftpState);
@@ -938,12 +933,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 +968,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 +1005,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 +1045,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);
@@ -1091,6 +1098,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 +1113,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 +1123,8 @@
 	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);
+	return;
     }
 }
 
@@ -1214,8 +1215,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,
@@ -1228,30 +1232,19 @@
     }
     debug(9, 5) ("ftpReadControlReply: FD %d, Read %d bytes\n", fd, len);
     if (len < 0) {
-	debug(50, 1) ("ftpReadControlReply: read error: %s\n", xstrerror());
+	debug(50, ignoreErrno(errno) ? 3 : 1) ("ftpReadControlReply: read error: %s\n", xstrerror());
 	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);
+	    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);
+	    return;
 	}
 	comm_close(ftpState->ctrl.fd);
 	return;
@@ -1312,6 +1305,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"))
@@ -1633,6 +1628,14 @@
     int fd;
     struct sockaddr_in addr;
     socklen_t addr_len;
+    if (ftpState->request->method == METHOD_HEAD) {
+	/* Terminate here for HEAD requests */
+	ftpAppendSuccessHeader(ftpState);
+	storeTimestampsSet(ftpState->entry);
+	fwdComplete(ftpState->fwd);
+	ftpSendQuit(ftpState);
+	return;
+    }
     if (ftpState->data.fd >= 0) {
 	if (!ftpState->flags.datachannel_hack) {
 	    /* We are already connected, reuse this connection. */
@@ -1677,6 +1680,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 +1701,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 +1735,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 +1745,12 @@
 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);
 	return;
     }
     ftpRestOrList(ftpState);
@@ -1761,6 +1765,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 +1846,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 +1886,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 +1906,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 +1927,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 +1938,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 +2130,21 @@
 {
     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);
+	return;
     }
-    ftpDataTransferDone(ftpState);
 }
 
 static void
@@ -2212,7 +2243,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,42 +2273,74 @@
 	    break;
 	}
     }
+    ftpFailed(ftpState, ERR_NONE);
+    return;
+}
+
+static void
+ftpFailed(FtpStateData *ftpState, err_type error)
+{
+    StoreEntry *entry = ftpState->entry;
+    if (entry->mem_obj->inmem_hi == 0) {
+	ftpFailedErrorMessage(ftpState, error);
+    }
+    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 ";
-    }
+	command = ftpState->ctrl.last_command;
+    if (command && strncmp(command, "PASS", 4) == 0)
+	command = "PASS ";
     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
@@ -2337,6 +2399,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 +2409,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/gopher.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/gopher.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/gopher.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/gopher.c	4 Feb 2000 16:41:12 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:12 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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/helper.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/helper.c	4 Feb 2000 16:41:12 -0000	1.1.1.2.2.1
@@ -18,7 +18,7 @@
     char *s;
     char *progname;
     char *shortname;
-    char *procname;
+    char *procname = NULL;
     char *args[HELPER_MAX_ARGS];
     char fd_note_buf[FD_DESC_SZ];
     helper_server *srv;
@@ -37,9 +37,13 @@
 	shortname = xstrdup(progname);
     debug(29, 1) ("helperOpenServers: Starting %d '%s' processes\n",
 	hlp->n_to_start, shortname);
+#if 0 /* dns_restarts requires dnsserver to know it's full pathname */
     procname = xmalloc(strlen(shortname) + 3);
     snprintf(procname, strlen(shortname) + 3, "(%s)", shortname);
     args[nargs++] = procname;
+#else
+    args[nargs++] = progname;
+#endif
     for (w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next)
 	args[nargs++] = w->key;
     args[nargs++] = NULL;
@@ -126,17 +130,18 @@
     storeAppendPrintf(sentry, "avg service time: %d msec\n",
 	hlp->stats.avg_svc_time);
     storeAppendPrintf(sentry, "\n");
-    storeAppendPrintf(sentry, "%7s\t%7s\t%11s\t%s\t%7s\t%7s\n",
+    storeAppendPrintf(sentry, "%7s\t%7s\t%11s\t%s\t%7s\t%7s\t%7s\n",
 	"#",
 	"FD",
 	"# Requests",
 	"Flags",
 	"Time",
-	"Offset");
+	"Offset",
+	"Request");
     for (link = hlp->servers.head; link; link = link->next) {
 	srv = link->data;
 	tt = 0.001 * tvSubMsec(srv->dispatch_time, current_time);
-	storeAppendPrintf(sentry, "%7d\t%7d\t%11d\t%c%c%c%c\t%7.3f\t%7d\n",
+	storeAppendPrintf(sentry, "%7d\t%7d\t%11d\t%c%c%c%c\t%7.3f\t%7d\t%s\n",
 	    srv->index + 1,
 	    srv->rfd,
 	    srv->stats.uses,
@@ -145,7 +150,8 @@
 	    srv->flags.closing ? 'C' : ' ',
 	    srv->flags.shutdown ? 'S' : ' ',
 	    tt < 0.0 ? 0.0 : tt,
-	    (int) srv->offset);
+	    (int) srv->offset,
+	    srv->request ? log_quote(srv->request->buf) : "(none)");
     }
     storeAppendPrintf(sentry, "\nFlags key:\n\n");
     storeAppendPrintf(sentry, "   A = ALIVE\n");
@@ -179,7 +185,8 @@
 	    continue;
 	}
 	srv->flags.closing = 1;
-	comm_close(srv->rfd);
+	comm_close(srv->wfd);
+	srv->wfd = -1;
     }
 }
 
@@ -223,7 +230,7 @@
 	helperRequestFree(r);
 	srv->request = NULL;
     }
-    if (srv->wfd != srv->rfd)
+    if (srv->wfd != srv->rfd && srv->wfd != -1)
 	comm_close(srv->wfd);
     dlinkDelete(&srv->link, &hlp->servers);
     hlp->n_running--;
@@ -283,9 +290,10 @@
 	    intAverage(hlp->stats.avg_svc_time,
 	    tvSubMsec(srv->dispatch_time, current_time),
 	    hlp->stats.replies, REDIRECT_AV_FACTOR);
-	if (srv->flags.shutdown)
+	if (srv->flags.shutdown) {
 	    comm_close(srv->wfd);
-	else
+	    srv->wfd = -1;
+	} else
 	    helperKickQueue(hlp);
     } else {
 	commSetSelect(srv->rfd, COMM_SELECT_READ, helperHandleRead, srv, 0);
@@ -307,7 +315,7 @@
     hlp->last_queue_warn = squid_curtime;
     debug(14, 0) ("WARNING: All %s processes are busy.\n", hlp->id_name);
     debug(14, 0) ("WARNING: %d pending requests queued\n", hlp->stats.queue_size);
-    if (hlp->stats.queue_size > hlp->n_running * 2)
+    if (hlp->stats.queue_size > hlp->n_running * 5)
 	fatalf("Too many queued %s requests", hlp->id_name);
     debug(14, 1) ("Consider increasing the number of %s processes in your config file.\n", hlp->id_name);
 }
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/http.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/http.c	4 Feb 2000 16:41:12 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:12 hno Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -131,7 +131,7 @@
 static void
 httpMaybeRemovePublic(StoreEntry * e, http_status status)
 {
-    int remove = 0;
+    int remove = 0, forbidden = 0;
     StoreEntry *pe;
     if (!EBIT_TEST(e->flags, KEY_PRIVATE))
 	return;
@@ -141,11 +141,14 @@
     case HTTP_MULTIPLE_CHOICES:
     case HTTP_MOVED_PERMANENTLY:
     case HTTP_MOVED_TEMPORARILY:
+    case HTTP_GONE:
+	remove = 1;
+	break;
     case HTTP_FORBIDDEN:
     case HTTP_NOT_FOUND:
     case HTTP_METHOD_NOT_ALLOWED:
-    case HTTP_GONE:
 	remove = 1;
+	forbidden = 1;
 	break;
 #if WORK_IN_PROGRESS
     case HTTP_UNAUTHORIZED:
@@ -153,7 +156,11 @@
 	break;
 #endif
     default:
-	remove = 0;
+	/* Any 2xx reply should eject previously cached entities... */
+	if (status >= 200 && status < 300)
+	    remove = 1;
+	else
+	    remove = 0;
 	break;
     }
     if (!remove)
@@ -163,9 +170,17 @@
 	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 reply in case the object has changed */
+    if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {
+	assert(e != pe);
+	storeRelease(pe);
+    }
+    if (forbidden)
+	return;
+    /* Remove the any cached GET reply when the entity can be expected
+     * to change as a result of other methods */
+    if (e->mem_obj->method != METHOD_GET) {
+	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_GET)) != NULL) {
 	    assert(e != pe);
 	    storeRelease(pe);
 	}
@@ -291,17 +306,20 @@
     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);
+    assert(httpState->reply_hdr_state == 0);
+	hdr_len = httpState->reply_hdr_size;
 	room = 8191 - hdr_len;
-	strncat(httpState->reply_hdr, buf, room < size ? room : size);
+	memcpy(httpState->reply_hdr + hdr_len, buf, room < size ? room : size);
 	hdr_len += room < size ? room : size;
+	httpState->reply_hdr[hdr_len] = '\0';
+	httpState->reply_hdr_size = hdr_len;
 	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;
@@ -311,22 +329,29 @@
 	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 */
+	    size_t k = headersEnd(httpState->reply_hdr, hdr_len);
+	    if (0 == k) {
+		if (hdr_len >= 8191 || room == 0) {
+		    debug(11, 3) ("httpProcessReplyHeader: Too large HTTP header: '%s'\n", httpState->reply_hdr);
+		    httpState->reply_hdr_state += 2;
+		    reply->sline.status = HTTP_INVALID_HEADER;
+		    return;
+		} else {
+		    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);
+    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);	/* httpState->eof); */
+    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);
@@ -358,14 +383,13 @@
 	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);
-	}
     }
+    ctx_exit(ctx);
 }
 
 static int
@@ -631,8 +655,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,8 +693,10 @@
 		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)
+	    /* Don't trust the client's Host: header unless the request is
+	     * redirected and redir_rewrites_host is off
+	     */
+	    if (request->flags.redirected && !Config.onoff.redir_rewrites_host)
 		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 	    break;
 	case HDR_IF_MODIFIED_SINCE:
@@ -745,9 +771,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 */
@@ -818,7 +844,7 @@
 
     debug(11, 5) ("httpSendRequest: FD %d: httpState %p.\n", httpState->fd, httpState);
 
-    if (pumpMethod(req->method))
+    if (httpState->orig_request->body)
 	sendHeaderDone = httpSendRequestEntry;
     else
 	sendHeaderDone = httpSendComplete;
@@ -835,14 +861,17 @@
     /*
      * Is keep-alive okay for all request methods?
      */
-    if (p == NULL)
+    if (Config.Timeout.pconn < 10)
+	httpState->flags.keepalive = 0;
+    else if (p == NULL)
 	httpState->flags.keepalive = 1;
     else if (p->stats.n_keepalives_sent < 10)
 	httpState->flags.keepalive = 1;
     else if ((double) p->stats.n_keepalives_recv / (double) p->stats.n_keepalives_sent > 0.50)
 	httpState->flags.keepalive = 1;
     if (httpState->peer)
-	if (neighborType(httpState->peer, httpState->request) == PEER_SIBLING)
+	if (neighborType(httpState->peer, httpState->request) == PEER_SIBLING &&
+		!httpState->peer->options.allow_miss)
 	    httpState->flags.only_if_cached = 1;
     memBufDefInit(&mb);
     httpBuildRequestPrefix(req,
@@ -878,7 +907,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/icmp.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/icmp.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.2.6.1
diff -u -r1.1.1.2 -r1.1.1.2.6.1
--- squid/src/icmp.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/icmp.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.6.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icmp.c,v 1.1.1.2 2000/01/26 03:23:10 hno Exp $
+ * $Id: icmp.c,v 1.1.1.2.6.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 37    ICMP Routines
  * AUTHOR: Duane Wessels
@@ -193,7 +193,7 @@
     int wfd;
     args[0] = "(pinger)";
     args[1] = NULL;
-    x = ipcCreate(IPC_UDP_SOCKET,
+    x = ipcCreate(IPC_DGRAM,
 	Config.Program.pinger,
 	args,
 	"Pinger Socket",
@@ -203,6 +203,7 @@
 	return;
     assert(rfd == wfd);
     icmp_sock = rfd;
+    fd_note (icmp_sock, "pinger");
     commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
     commSetTimeout(icmp_sock, -1, NULL, NULL);
     debug(29, 1) ("Pinger socket opened on FD %d\n", icmp_sock);
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/internal.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/internal.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 76    Internal Squid Object handling
  * AUTHOR: Duane, Alex, Henrik
@@ -99,7 +99,7 @@
 char *
 internalLocalUri(const char *dir, const char *name)
 {
-    return internalRemoteUri(getMyHostname(), Config.Port.http->i, dir, name);
+    return internalRemoteUri(getMyHostname(), Config.Port.http->port, dir, name);
 }
 
 const char *
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/ipc.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ipc.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 54    Interprocess Communication
  * AUTHOR: Duane Wessels
@@ -123,6 +123,24 @@
 	fd_open(cwfd = p2c[1], FD_PIPE, "IPC FIFO Child Write");
 	fd_open(crfd = c2p[0], FD_PIPE, "IPC FIFO Child Read");
 	fd_open(pwfd = c2p[1], FD_PIPE, "IPC FIFO Parent Write");
+#if HAVE_SOCKETPAIR && defined(AF_UNIX)
+    } else if (type == IPC_UNIX_STREAM) {
+	int fds[2];
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
+	    debug(50, 0) ("ipcCreate: socketpair: %s\n", xstrerror());
+	    return -1;
+	}
+	fd_open(prfd = pwfd = fds[0], FD_PIPE, "IPC UNIX STREAM Parent");
+	fd_open(crfd = cwfd = fds[1], FD_PIPE, "IPC UNIX STREAM Parent");
+    } else if (type == IPC_UNIX_DGRAM) {
+	int fds[2];
+	if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) < 0) {
+	    debug(50, 0) ("ipcCreate: socketpair: %s\n", xstrerror());
+	    return -1;
+	}
+	fd_open(prfd = pwfd = fds[0], FD_PIPE, "IPC UNIX DGRAM Parent");
+	fd_open(crfd = cwfd = fds[1], FD_PIPE, "IPC UNIX DGRAM Parent");
+#endif
     } else {
 	assert(IPC_NONE);
     }
@@ -227,14 +245,14 @@
 	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
     if (type == IPC_UDP_SOCKET) {
-	x = send(cwfd, hello_string, strlen(hello_string), 0);
+	x = send(cwfd, hello_string, strlen(hello_string) + 1, 0);
 	if (x < 0) {
 	    debug(50, 0) ("sendto FD %d: %s\n", cwfd, xstrerror());
 	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");
 	    _exit(1);
 	}
     } else {
-	if (write(cwfd, hello_string, strlen(hello_string)) < 0) {
+	if (write(cwfd, hello_string, strlen(hello_string) + 1) < 0) {
 	    debug(50, 0) ("write FD %d: %s\n", cwfd, xstrerror());
 	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");
 	    _exit(1);
@@ -266,10 +284,14 @@
     close(t1);
     close(t2);
     close(t3);
+    /* Make sure all other filedescriptors are closed */
+    for(x=3;xlocks != 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;
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/main.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/main.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -350,12 +350,18 @@
 mainRotate(void)
 {
     icmpClose();
+    dnsShutdown();
+    redirectShutdown();
+    authenticateShutdown();
     _db_rotate_log();		/* cache.log */
     storeDirWriteCleanLogs(1);
     storeLogRotate();		/* store.log */
     accessLogRotate();		/* access.log */
     useragentRotateLog();	/* useragent.log */
     icmpOpen();
+    dnsInit();
+    redirectInit();
+    authenticateInit();
 }
 
 static void
@@ -405,6 +411,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);
@@ -415,7 +425,7 @@
     setEffectiveUser();
     assert(Config.Port.http);
     if (httpPortNumOverride != 1)
-	Config.Port.http->i = (u_short) httpPortNumOverride;
+	Config.Port.http->port = (u_short) httpPortNumOverride;
     if (icpPortNumOverride != 1)
 	Config.Port.icp = (u_short) icpPortNumOverride;
 
@@ -478,6 +488,9 @@
 	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 */
 
@@ -569,10 +582,18 @@
 
     /* 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();
@@ -703,7 +724,7 @@
 	close(i);
     }
 #endif
-    for (i = 0; i < Squid_MaxFD; i++)
+    for (i = 3; i < Squid_MaxFD; i++)
 	close(i);
 #if NOT_NEEDED
     umask(0);
@@ -758,11 +779,6 @@
 SquidShutdown(void *unused)
 {
     debug(1, 1) ("Shutting down...\n");
-    if (Config.pidFilename && strcmp(Config.pidFilename, "none")) {
-	enter_suid();
-	safeunlink(Config.pidFilename, 0);
-	leave_suid();
-    }
     icpConnectionClose();
 #if USE_HTCP
     htcpSocketClose();
@@ -822,5 +838,10 @@
     debug(1, 1) ("Squid Cache (Version %s): Exiting normally.\n",
 	version_string);
     fclose(debug_log);
+    if (Config.pidFilename && strcmp(Config.pidFilename, "none")) {
+	enter_suid();
+	unlink(Config.pidFilename);
+	leave_suid();
+    }
     exit(0);
 }
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/neighbors.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/neighbors.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -48,9 +48,9 @@
 static void neighborCountIgnored(peer *);
 static void peerRefreshDNS(void *);
 static IPH peerDNSConfigure;
-static EVH peerCheckConnect;
-static IPH peerCheckConnect2;
-static CNCB peerCheckConnectDone;
+static void peerProbeConnect(peer *);
+static IPH peerProbeConnect2;
+static CNCB peerProbeConnectDone;
 static void peerCountMcastPeersDone(void *data);
 static void peerCountMcastPeersStart(void *data);
 static void peerCountMcastPeersSchedule(peer * p, time_t when);
@@ -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);
 }
@@ -162,15 +163,17 @@
 	return 0;
     if (p->options.mcast_responder)
 	return 0;
+    if (p->n_addresses == 0)
+	return 0;
     /* the case below seems strange, but can happen if the
      * URL host is on the other side of a firewall */
     if (p->type == PEER_SIBLING)
 	if (!request->flags.hierarchical)
 	    return 0;
-    if (p->icp.port == echo_port)
-	if (!neighborUp(p))
-	    return 0;
-    if (p->n_addresses == 0)
+    /* Ping dead peers every timeout interval */
+    if (squid_curtime - p->stats.last_query > Config.Timeout.deadPeer)
+	return 1;
+    if (!neighborUp(p))
 	return 0;
     return 1;
 }
@@ -236,6 +239,34 @@
 }
 
 peer *
+getLowestRttParent(request_t * request)
+{
+    peer *p;
+    peer *p_rtt = NULL;
+    for (p = Config.peers; p; p = p->next) {
+	if (!p->stats.icp_last_reply_ok)
+	    continue;
+	if (!neighborUp(p))
+	    continue;
+	if (neighborType(p, request) != PEER_PARENT)
+	    continue;
+	if (!peerHTTPOkay(p, request))
+	    continue;
+	if (!peerWouldBePinged(p, request))
+	    continue;
+	if (!p_rtt || p->stats.rtt < p_rtt->stats.rtt)
+	    p_rtt = p;
+    }
+    if (p_rtt)
+	debug(15, 3) ("getLowestRttParent: returning %s RTT %d msec\n", p_rtt->host, p_rtt->stats.rtt);
+    else
+	debug(15, 4) ("getLowestRttParent: none found\n");
+    return p_rtt;
+}
+
+
+
+peer *
 getRoundRobinParent(request_t * request)
 {
     peer *p;
@@ -371,6 +402,8 @@
     icp_common_t *query;
     int queries_sent = 0;
     int peers_pinged = 0;
+    int parent_timeout = 0, parent_exprep = 0;
+    int sibling_timeout = 0, sibling_exprep = 0;
 
     if (Config.peers == NULL)
 	return 0;
@@ -380,7 +413,6 @@
     mem->start_ping = current_time;
     mem->ping_reply_callback = callback;
     mem->ircb_data = callback_data;
-    *timeout = 0.0;
     reqnum = icpSetCacheKey(entry->key);
     for (i = 0, p = first_ping; i++ < Config.npeers; p = p->next) {
 	if (p == NULL)
@@ -433,28 +465,15 @@
 	     */
 	    p->stats.last_reply = squid_curtime;
 	    (*exprep) += p->mcast.n_replies_expected;
-	} else if (squid_curtime - p->stats.last_query > Config.Timeout.deadPeer) {
-	    /*
-	     * fake a recent reply if its been a long time since our
-	     * last query
-	     */
-	    p->stats.last_reply = squid_curtime;
-	    /*
-	     * We used to not expect a reply in this case; we assumed
-	     * the peer was DEAD if we hadn't queried it in a long
-	     * time.  However, the number of people whining to
-	     * squid-users that ICP is broken became unbearable.  They
-	     * tried a single request which, to their amazement, was
-	     * forwarded directly to the origin server, even thought
-	     * they KNEW it was in a neighbor cache.  Ok, I give up, you
-	     * win!
-	     */
-	    (*exprep)++;
-	    (*timeout) += 1000;
 	} else if (neighborUp(p)) {
 	    /* its alive, expect a reply from it */
-	    (*exprep)++;
-	    (*timeout) += p->stats.rtt;
+	    if (neighborType(p, request) == PEER_PARENT) {
+		parent_exprep++;
+		parent_timeout += p->stats.rtt;
+	    } else {
+		sibling_exprep++;
+		sibling_timeout += p->stats.rtt;
+	    }
 	} else {
 	    /* Neighbor is dead; ping it anyway, but don't expect a reply */
 	    /* log it once at the threshold */
@@ -466,6 +485,8 @@
 	    }
 	}
 	p->stats.last_query = squid_curtime;
+	if (p->stats.probe_start == 0)
+	    p->stats.probe_start = squid_curtime;
     }
     if ((first_ping = first_ping->next) == NULL)
 	first_ping = Config.peers;
@@ -502,12 +523,20 @@
     }
 #endif
     /*
+     * How many replies to expect?
+     */
+    *exprep = parent_exprep + sibling_exprep;
+    /*
      * If there is a configured timeout, use it
      */
     if (Config.Timeout.icp_query)
 	*timeout = Config.Timeout.icp_query;
     else if (*exprep > 0)
-	(*timeout) = 2 * (*timeout) / (*exprep);
+	/* Else use a calculated timeout */
+	if (parent_exprep)
+	    *timeout = 2 * parent_timeout / parent_exprep;
+	else
+	    *timeout = 2 * sibling_timeout / sibling_exprep;
     else
 	*timeout = 2000;	/* 2 seconds */
     return peers_pinged;
@@ -627,6 +656,7 @@
 	p->stats.logged_state = PEER_ALIVE;
     }
     p->stats.last_reply = squid_curtime;
+    p->stats.probe_start = 0;
     p->stats.pings_acked++;
     if ((icp_opcode) header->opcode <= ICP_END)
 	p->icp.counts[header->opcode]++;
@@ -659,6 +689,7 @@
 	p->stats.logged_state = PEER_ALIVE;
     }
     p->stats.last_reply = squid_curtime;
+    p->stats.probe_start = 0;
     p->stats.pings_acked++;
     p->htcp.counts[htcp->hit ? 1 : 0]++;
     p->htcp.version = htcp->version;
@@ -750,8 +781,20 @@
     if (opcode > ICP_END)
 	return;
     opcode_d = icp_opcode_str[opcode];
-    if (p)
+    if (p) {
 	neighborUpdateRtt(p, mem);
+	switch(opcode) {
+	case ICP_HIT:
+	case ICP_MISS:
+	case ICP_HIT_OBJ:
+	case ICP_DECHO:
+	    p->stats.icp_last_reply_ok = 1;
+	    break;
+	default:
+	    p->stats.icp_last_reply_ok = 0;
+	    break;
+	}
+    }
     /* Does the entry exist? */
     if (NULL == entry) {
 	debug(12, 3) ("neighborsUdpAck: Cache key '%s' not found\n",
@@ -872,11 +915,14 @@
 int
 neighborUp(const peer * p)
 {
-    if (!p->tcp_up)
+    if (!p->tcp_up) {
+	peerProbeConnect((peer *)p);
 	return 0;
-    if (squid_curtime - p->stats.last_query > Config.Timeout.deadPeer)
+    }
+    if (p->options.no_query)
 	return 1;
-    if (p->stats.last_query - p->stats.last_reply > Config.Timeout.deadPeer)
+    if (p->stats.probe_start != 0 &&
+	    squid_curtime - p->stats.probe_start > Config.Timeout.deadPeer)
 	return 0;
     return 1;
 }
@@ -972,62 +1018,82 @@
     eventAddIsh("peerRefreshDNS", peerRefreshDNS, NULL, 3600.0, 1);
 }
 
+void
+peerConnectFailed(peer *p)
+{
+    p->stats.last_connect_failure = squid_curtime;
+    if (!p->tcp_up) {
+	debug(15, 2) ("TCP connection to %s/%d dead\n", p->host, p->http_port);
+	return;
+    }
+    debug(15, 1) ("TCP connection to %s/%d failed\n", p->host, p->http_port);
+    p->tcp_up--;
+    if (!p->tcp_up) {
+	debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n",
+	    neighborTypeStr(p),
+	    p->host, p->http_port, p->icp.port);
+	p->stats.logged_state = PEER_DEAD;
+    }
+}
+
+void
+peerConnectSucceded(peer *p)
+{
+    if (!p->tcp_up) {
+	debug(15, 2) ("TCP connection to %s/%d succeded\n", p->host, p->http_port);
+	debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",
+	    neighborTypeStr(p),
+	    p->host, p->http_port, p->icp.port);
+	p->stats.logged_state = PEER_ALIVE;
+    }
+    p->tcp_up = PEER_TCP_MAGIC_COUNT;
+}
+
 /*
- * peerCheckConnect will NOT be called by eventRun if the peer/data
- * pointer becomes invalid.
+ * peerProbeConnect will be called on dead peers by neighborUp 
  */
 static void
-peerCheckConnect(void *data)
+peerProbeConnect(peer *p)
 {
-    peer *p = data;
     int fd;
+    if (p->test_fd != -1)
+	return; /* probe already running */
+    if (squid_curtime - p->stats.last_connect_probe < Config.Timeout.connect)
+	return; /* don't probe to often */
     fd = comm_open(SOCK_STREAM, 0, Config.Addrs.tcp_outgoing,
 	0, COMM_NONBLOCKING, p->host);
     if (fd < 0)
 	return;
     p->test_fd = fd;
-    ipcache_nbgethostbyname(p->host, peerCheckConnect2, p);
+    p->stats.last_connect_probe = squid_curtime;
+    ipcache_nbgethostbyname(p->host, peerProbeConnect2, p);
 }
 
 static void
-peerCheckConnect2(const ipcache_addrs * ianotused, void *data)
+peerProbeConnect2(const ipcache_addrs * ianotused, void *data)
 {
     peer *p = data;
     commConnectStart(p->test_fd,
 	p->host,
 	p->http_port,
-	peerCheckConnectDone,
+	peerProbeConnectDone,
 	p);
 }
 
 static void
-peerCheckConnectDone(int fd, int status, void *data)
+peerProbeConnectDone(int fd, int status, void *data)
 {
     peer *p = data;
     if (status == COMM_OK) {
-	p->tcp_up = PEER_TCP_MAGIC_COUNT;
-	debug(15, 1) ("TCP connection to %s/%d succeeded\n",
-	    p->host, p->http_port);
+	peerConnectSucceded(p);
     } else {
-	eventAdd("peerCheckConnect", peerCheckConnect, p, 60.0, 1);
+	peerConnectFailed(p);
     }
     comm_close(fd);
+    p->test_fd = -1;
     return;
 }
 
-void
-peerCheckConnectStart(peer * p)
-{
-    if (!p->tcp_up)
-	return;
-    debug(15, 1) ("TCP connection to %s/%d failed\n", p->host, p->http_port);
-    p->tcp_up--;
-    if (p->tcp_up != (PEER_TCP_MAGIC_COUNT - 1))
-	return;
-    p->last_fail_time = squid_curtime;
-    eventAdd("peerCheckConnect", peerCheckConnect, p, 30.0, 1);
-}
-
 static void
 peerCountMcastPeersSchedule(peer * p, time_t when)
 {
@@ -1230,9 +1296,9 @@
 #if USE_HTCP
 	}
 #endif
-	if (e->last_fail_time) {
+	if (e->stats.last_connect_failure) {
 	    storeAppendPrintf(sentry, "Last failed connect() at: %s\n",
-		mkhttpdlogtime(&(e->last_fail_time)));
+		mkhttpdlogtime(&(e->stats.last_connect_failure)));
 	}
 	if (e->peer_domain != NULL) {
 	    storeAppendPrintf(sentry, "DOMAIN LIST: ");
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/net_db.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/net_db.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 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,7 @@
     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);
+    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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/peer_digest.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/peer_digest.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 72    Peer Digest Routines
  * AUTHOR: Alex Rousskov
@@ -317,7 +317,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 +330,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 +411,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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/peer_select.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/peer_select.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 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",
@@ -88,6 +89,7 @@
 static void peerGetSomeNeighborReplies(ps_state *);
 static void peerGetSomeDirect(ps_state *);
 static void peerGetSomeParent(ps_state *);
+static void peerGetAllParents(ps_state *);
 static void peerAddFwdServer(FwdServer **, peer *, hier_code);
 
 static void
@@ -208,6 +210,8 @@
     int myhops;
     if (p == NULL)
 	return 0;
+    if (psstate->direct == DIRECT_NO)
+	return 0;
     myrtt = netdbHostRtt(psstate->request->host);
     debug(44, 3) ("peerCheckNetdbDirect: MY RTT = %d msec\n", myrtt);
     debug(44, 3) ("peerCheckNetdbDirect: closest_parent_miss RTT = %d msec\n",
@@ -236,8 +240,6 @@
 	    ps->acl_checklist = aclChecklistCreate(
 		Config.accessList.AlwaysDirect,
 		request,
-		request->client_addr,
-		request->my_addr,
 		NULL,		/* user agent */
 		NULL);		/* ident */
 	    aclNBCheck(ps->acl_checklist,
@@ -250,8 +252,6 @@
 	    ps->acl_checklist = aclChecklistCreate(
 		Config.accessList.NeverDirect,
 		request,
-		request->client_addr,
-		request->my_addr,
 		NULL,		/* user agent */
 		NULL);		/* ident */
 	    aclNBCheck(ps->acl_checklist,
@@ -278,11 +278,23 @@
 	peerGetSomeNeighborReplies(ps);
 	entry->ping_status = PING_DONE;
     }
-    if (Config.onoff.prefer_direct)
-	peerGetSomeDirect(ps);
-    peerGetSomeParent(ps);
-    if (!Config.onoff.prefer_direct)
+    switch (ps->direct) {
+    case DIRECT_YES:
 	peerGetSomeDirect(ps);
+	break;
+    case DIRECT_NO:
+	peerGetSomeParent(ps);
+	peerGetAllParents(ps);
+	break;
+    default:
+	if (Config.onoff.prefer_direct)
+	    peerGetSomeDirect(ps);
+	if (request->flags.hierarchical || !Config.onoff.nonhierarchical_direct)
+	    peerGetSomeParent(ps);
+	if (!Config.onoff.prefer_direct)
+	    peerGetSomeDirect(ps);
+	break;
+    }
     peerSelectCallback(ps);
 }
 
@@ -310,7 +322,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
@@ -382,6 +397,10 @@
     if (ps->closest_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
 	p = whichPeer(&ps->closest_parent_miss);
 	code = CLOSEST_PARENT_MISS;
+    } else if (ps->ping.timedout) {
+	/* ICP pinging timedout, use estimated rtt's for selecing parent */
+	p = getLowestRttParent(request);
+	code = FIRST_PARENT_MISS;
     } else if (ps->first_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
 	p = whichPeer(&ps->first_parent_miss);
 	code = FIRST_PARENT_MISS;
@@ -437,6 +456,35 @@
     }
 }
 
+/* Adds alive parents. Used as a last resort for never_direct.
+ */
+static void
+peerGetAllParents(ps_state * ps)
+{
+    peer *p;
+    request_t *request = ps->request;
+    /* Add all alive parents */
+    for (p = Config.peers; p; p = p->next) {
+	/* XXX: neighbors.c lacks a public interface for enumerating
+	 * parents to a request so we have to dig some here..
+	 */
+	if (neighborType(p, request) != PEER_PARENT)
+	    continue;
+	if (!peerHTTPOkay(p, request))
+	    continue;
+	debug(15, 3) ("peerGetAllParents: adding alive parent %s\n", p->host);
+	peerAddFwdServer(&ps->servers, p, ANY_OLD_PARENT);
+    }
+    /* XXX: should add dead parents here, but it is currently
+     * not possible to find out which parents are dead or which
+     * simply are not configured to handle the request.
+     */
+    /* Add default parent as a last resort */
+    if ((p = getDefaultParent(request))) {
+	peerAddFwdServer(&ps->servers, p, DEFAULT_PARENT);
+    }
+}
+
 static void
 peerPingTimeout(void *data)
 {
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/protos.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/protos.h	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -41,11 +41,10 @@
 extern void fvdbCountVia(const char *key);
 extern void fvdbCountForw(const char *key);
 #endif
+char *log_quote(const char *header);
 
 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 *);
@@ -77,6 +76,9 @@
 extern int aio_opendir(const char *, aio_result_t *);
 extern aio_result_t *aio_poll_done(void);
 extern int aio_operations_pending(void);
+extern int aio_overloaded(void);
+extern int aio_sync(void);
+extern int aio_get_queue_len(void);
 
 extern void aioCancel(int, void *);
 extern void aioOpen(const char *, int, mode_t, AIOCB *, void *, void *);
@@ -437,7 +439,7 @@
 /* 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, size_t);
 extern void httpReplyPackInto(const HttpReply * rep, Packer * p);
 /* ez-routines */
 /* mem-pack: returns a ready to use mem buffer with a packed reply */
@@ -587,6 +589,7 @@
 
 extern peer *getFirstPeer(void);
 extern peer *getFirstUpParent(request_t *);
+extern peer *getLowestRttParent(request_t *);
 extern peer *getNextPeer(peer *);
 extern peer *getSingleParent(request_t *);
 extern int neighborsCount(request_t *);
@@ -613,7 +616,8 @@
 extern CBDUNL peerDestroy;
 extern char *neighborTypeStr(const peer * e);
 extern peer_t neighborType(const peer *, const request_t *);
-extern void peerCheckConnectStart(peer *);
+extern void peerConnectFailed(peer *);
+extern void peerConnectSucceded(peer *);
 extern void dump_peer_options(StoreEntry *, peer *);
 extern int peerHTTPOkay(const peer *, request_t *);
 extern peer *whichPeer(const struct sockaddr_in *from);
@@ -654,7 +658,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 *);
@@ -1038,6 +1042,7 @@
 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 unsigned char *);
 
 #if USE_HTCP
 extern void htcpInit(void);
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/pump.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/pump.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 61    PUMP handler
  * AUTHOR: Kostas Anagnostakis
@@ -230,6 +230,12 @@
     cbdataUnlock(p->cbdata);
     storeUnlockObject(p->reply_entry);
     p->reply_entry = NULL;
+    /*
+     * and now we don't care about the client side either
+     * tear down the pump state.
+     */
+    comm_remove_close_handler(p->c_fd, pumpFree, p);
+    pumpFree(p->c_fd, p);
 }
 
 
@@ -408,25 +414,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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/redirect.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/redirect.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 29    Redirector
  * AUTHOR: Duane Wessels
@@ -133,7 +133,7 @@
 	redirectors = helperCreate("redirector");
     wordlistAdd(&redirectors->cmdline, Config.Program.redirect);
     redirectors->n_to_start = Config.redirectChildren;
-    redirectors->ipc_type = IPC_TCP_SOCKET;
+    redirectors->ipc_type = IPC_STREAM;
     helperOpenServers(redirectors);
     if (!init) {
 	cachemgrRegister("redirector",
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/send-announce.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/send-announce.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 27    Cache Announcer
  * AUTHOR: Duane Wessels
@@ -75,7 +75,7 @@
     assert(Config.Port.http);
     snprintf(tbuf, 256, "Running on %s %d %d\n",
 	getMyHostname(),
-	(int) Config.Port.http->i,
+	(int) Config.Port.http->port,
 	(int) Config.Port.icp);
     strcat(sndbuf, tbuf);
     if (Config.adminEmail) {
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/squid.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/squid.h	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -320,7 +320,7 @@
 #include 
 #endif
 
-#if USE_ASYNC_IO
+#if USE_ASYNC_IO_UNLINK
 #undef USE_UNLINKD
 #else
 #define USE_UNLINKD 1
@@ -389,5 +389,10 @@
 extern struct snmp_mib_tree *Mib;
 #endif
 
+#if defined(O_NONBLOCK) && !defined(_SQUID_SUNOS_) && !defined(_SQUID_SOLARIS_)
+#define SQUID_NONBLOCK O_NONBLOCK
+#else
+#define SQUID_NONBLOCK O_NDELAY
+#endif
 
 #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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/ssl.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/ssl.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -371,6 +371,13 @@
     SslStateData *sslState = data;
     request_t *request = sslState->request;
     ErrorState *err = NULL;
+    if (sslState->servers->peer) {
+	hierarchyNote(&sslState->request->hier, sslState->servers->code,
+	    sslState->servers->peer->host);
+    } else {
+	hierarchyNote(&sslState->request->hier, sslState->servers->code,
+		fd_table[sslState->server.fd].ipaddr);
+    }
     if (status == COMM_ERR_DNS) {
 	debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host);
 	err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND);
@@ -527,6 +534,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) {
@@ -534,9 +547,6 @@
 	sslState->delay_id = 0;
     }
 #endif
-    hierarchyNote(&sslState->request->hier,
-	fs->peer ? fs->code : DIRECT,
-	sslState->host);
     commConnectStart(sslState->server.fd,
 	sslState->host,
 	sslState->port,
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/stat.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/stat.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -66,6 +66,8 @@
 #if DEBUG_OPENFD
 static OBJH statOpenfdObj;
 #endif
+static OBJH statLargeVmObjects;
+static OBJH statLostObjects;
 static EVH statObjects;
 static OBJH info_get;
 static OBJH statFiledescriptors;
@@ -304,32 +306,36 @@
 {
     StatObjectsState *state = data;
     StoreEntry *e;
+    int n = 0;
     hash_link *link_ptr = NULL;
     hash_link *link_next = NULL;
-    if (state->bucket >= store_hash_buckets) {
-	storeComplete(state->sentry);
-	storeUnlockObject(state->sentry);
-	cbdataFree(state);
-	return;
-    } else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) {
-	storeUnlockObject(state->sentry);
-	cbdataFree(state);
-	return;
-    } else if (fwdCheckDeferRead(-1, state->sentry)) {
-	eventAdd("statObjects", statObjects, state, 0.1, 1);
-	return;
-    }
-    storeBuffer(state->sentry);
-    debug(49, 3) ("statObjects: Bucket #%d\n", state->bucket);
-    link_next = hash_get_bucket(store_table, state->bucket);
-    while (NULL != (link_ptr = link_next)) {
-	link_next = link_ptr->next;
-	e = (StoreEntry *) link_ptr;
-	if (state->filter && 0 == state->filter(e))
-	    continue;
-	statStoreEntry(state->sentry, e);
+    for (n = 0; n < 100; n++) {
+	if (state->bucket >= store_hash_buckets) {
+	    storeComplete(state->sentry);
+	    storeUnlockObject(state->sentry);
+	    cbdataFree(state);
+	    return;
+	} else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) {
+	    storeUnlockObject(state->sentry);
+	    cbdataFree(state);
+	    return;
+	} else if (fwdCheckDeferRead(-1, state->sentry)) {
+	    eventAdd("statObjects", statObjects, state, 0.1, 1);
+	    return;
+	}
+	storeBuffer(state->sentry);
+	debug(49, 3) ("statObjects: Bucket #%d\n", state->bucket);
+	link_next = hash_get_bucket(store_table, state->bucket);
+	while (NULL != (link_ptr = link_next)) {
+	    link_next = link_ptr->next;
+	    e = (StoreEntry *) link_ptr;
+	    if (state->filter && 0 == state->filter(e))
+		continue;
+	    statStoreEntry(state->sentry, e);
+	    n++;
+	}
+	state->bucket++;
     }
-    state->bucket++;
     eventAdd("statObjects", statObjects, state, 0.0, 1);
     storeBufferFlush(state->sentry);
 }
@@ -363,6 +369,34 @@
     statObjectsStart(sentry, statObjectsVmFilter);
 }
 
+static int
+statLargeVmObjectsFilter(const StoreEntry * e)
+{
+    MemObject *mem = e->mem_obj;
+    if (!mem)
+	return 0;
+
+    return mem->inmem_hi - mem->inmem_lo > Config.memMaxSize / 64;
+}
+
+static void
+statLargeVmObjects(StoreEntry * sentry)
+{
+    statObjectsStart(sentry, statLargeVmObjectsFilter);
+}
+
+static int
+statLostOjectsFilter(const StoreEntry * e)
+{
+    return !e->mem_obj && e->swap_file_number == -1;
+}
+
+static void
+statLostObjects(StoreEntry * sentry)
+{
+    statObjectsStart(sentry, statLostOjectsFilter);
+}
+
 #if DEBUG_OPENFD
 static int
 statObjectsOpenfdFilter(const StoreEntry * e)
@@ -830,6 +864,12 @@
     cachemgrRegister("vm_objects",
 	"In-Memory and In-Transit Objects",
 	stat_vmobjects_get, 0, 0);
+    cachemgrRegister("vm_largeobjects",
+	"Large In-Memory and In-Transit Objects",
+	statLargeVmObjects, 0, 0);
+    cachemgrRegister("lostobjects",
+	"Lost StoreEntry structures",
+	statLostObjects, 0, 0);
 #if DEBUG_OPENFD
     cachemgrRegister("openfd_objects",
 	"Objects with Swapout files open",
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/store.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
@@ -501,7 +501,9 @@
 	debug(20, 3) ("storeCheckCachable: NO: negative cached\n");
 	store_check_cachable_hist.no.negative_cached++;
 	return 0;		/* avoid release call below */
-    } else if (e->mem_obj->inmem_hi > Config.Store.maxObjectSize) {
+    } else if ((e->mem_obj->reply->content_length > 0 &&
+		e->mem_obj->reply->content_length > Config.Store.maxObjectSize) ||
+		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 (EBIT_TEST(e->flags, KEY_PRIVATE)) {
@@ -514,6 +516,10 @@
 	 * out the object yet.
 	 */
 	return 1;
+#if USE_ASYNC_IO
+    } else if (aio_overloaded()) {
+	debug(20, 2) ("storeCheckCachable: NO: Async-IO overloaded\n");
+#endif
     } else if (storeTooManyDiskFilesOpen()) {
 	debug(20, 2) ("storeCheckCachable: NO: too many disk files open\n");
 	store_check_cachable_hist.no.too_many_open_files++;
@@ -664,8 +670,10 @@
     pages_needed = (size / SM_PAGE_SIZE) + 1;
     if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
 	return;
+#if DONT_DO_THIS_HERE
     if (store_rebuilding)
 	return;
+#endif
     debug(20, 2) ("storeGetMemSpace: Starting, need %d pages\n", pages_needed);
     head = inmem_list.head;
     for (m = inmem_list.tail; m; m = prev) {
@@ -792,12 +800,16 @@
 	    storeSetMemStatus(e, NOT_IN_MEMORY);
 	    destroy_MemObject(e);
 	}
-	/*
-	 * Fake a call to storeLockObject().  When rebuilding is done,
-	 * we'll just call storeUnlockObject() on these.
-	 */
-	e->lock_count++;
-	stackPush(&LateReleaseStack, e);
+	if (e->swap_file_number > -1) {
+	    /*
+	     * Fake a call to storeLockObject().  When rebuilding is done,
+	     * we'll just call storeUnlockObject() on these.
+	     */
+	    e->lock_count++;
+	    stackPush(&LateReleaseStack, e);
+	} else {
+	    destroy_StoreEntry(e);
+	}
 	return;
     }
     storeLog(STORE_LOG_RELEASE, e);
@@ -1063,11 +1075,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;
@@ -1201,10 +1228,10 @@
 storeUnlinkFileno(int fileno)
 {
     debug(20, 5) ("storeUnlinkFileno: %08X\n", fileno);
-#if USE_ASYNC_IO
-    safeunlink(storeSwapFullPath(fileno, NULL), 1);
-#else
+#if USE_UNLINKD
     unlinkdUnlink(storeSwapFullPath(fileno, NULL));
+#else
+    safeunlink(storeSwapFullPath(fileno, NULL), 1);
 #endif
 }
 
@@ -1243,4 +1270,5 @@
     mem->inmem_hi = mem->inmem_lo = 0;
     httpReplyDestroy(mem->reply);
     mem->reply = httpReplyCreate();
+    e->expires = e->lastmod = e->timestamp = -1;
 }
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/store_client.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_client.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Client-Side Interface
  * AUTHOR: Duane Wessels
@@ -346,7 +346,7 @@
     assert(sc->callback != NULL);
     debug(20, 3) ("storeClientReadBody: FD %d, len %d\n", fd, 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);
 }
@@ -361,7 +361,8 @@
     int swap_hdr_sz = 0;
     size_t body_sz;
     size_t copy_sz;
-    tlv *tlv_list;
+    tlv *tlv_list, *t;
+    int swap_object_ok = 1;
     assert(sc->flags.disk_io_pending);
     sc->flags.disk_io_pending = 0;
     assert(sc->callback != NULL);
@@ -380,10 +381,38 @@
 	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) {
+#if 0 /* Probably not a good idea.. may race with other requests making this object private.. */
+	case STORE_META_KEY:
+	    assert(t->length == MD5_DIGEST_CHARS);
+	    if (memcmp(t->value, e->key, MD5_DIGEST_CHARS) != 0) {
+		debug(20, 1) ("storeClientReadHeader: Swap object key does not match\n");
+		swap_object_ok = 0;
+		break;
+	    }
+	    break;
+#endif
+	case STORE_META_URL:
+	    if (mem->url) {
+		if (strcasecmp(mem->url, t->value) != 0) {
+		    debug(20, 1) ("storeClientReadHeader: Swap object URL does not match, %s != %s\n", t->value, mem->url);
+		    swap_object_ok = 0;
+		    break;
+		}
+	    }
+	    break;
+	}
+    }
     storeSwapTLVFree(tlv_list);
+    if (!swap_object_ok) {
+	debug(20, 1) ("storeClientReadHeader: Swap object does not match meta data\n");
+	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 +429,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;
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/store_dir.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_dir.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 47    Store Directory Routines
  * AUTHOR: Duane Wessels
@@ -38,6 +38,13 @@
 #if HAVE_SYS_STATVFS_H
 #include 
 #endif
+#elif HAVE_STATFS
+#if HAVE_SYS_VFS_H
+#include 
+#endif
+#if HAVE_SYS_MOUNT_H
+#include 
+#endif
 #endif
 
 #define SWAP_DIR_SHIFT 24
@@ -438,12 +445,24 @@
 storeDirSwapLogFile(int dirn, const char *ext)
 {
     LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);
+    LOCAL_ARRAY(char, pathtmp, SQUID_MAXPATHLEN);
     LOCAL_ARRAY(char, digit, 32);
+    char *pathtmp2;
     if (Config.Log.swap) {
-	xstrncpy(path, Config.Log.swap, SQUID_MAXPATHLEN - 64);
-	strcat(path, ".");
-	snprintf(digit, 32, "%02d", dirn);
-	strncat(path, digit, 3);
+	xstrncpy(pathtmp, storeSwapDir(dirn), SQUID_MAXPATHLEN);
+	while (index(pathtmp,'/'))
+		*index(pathtmp,'/')='.';
+	while (strlen(pathtmp) && pathtmp[strlen(pathtmp)-1]=='.')
+	    pathtmp[strlen(pathtmp)-1]= '\0';
+	pathtmp2 = pathtmp;
+	while (*pathtmp2 == '.')
+	    pathtmp2 += 1;
+	snprintf(path, SQUID_MAXPATHLEN, Config.Log.swap, pathtmp2);
+	if (strcmp(path, Config.Log.swap) == 0) {
+	    strcat(path, ".");
+	    snprintf(digit, 32, "%02d", dirn);
+	    strncat(path, digit, 3);
+	}
     } else {
 	xstrncpy(path, storeSwapDir(dirn), SQUID_MAXPATHLEN - 64);
 	strcat(path, "/swap.state");
@@ -586,6 +605,8 @@
     SwapDir *SD;
 #if HAVE_STATVFS
     struct statvfs sfs;
+#elif HAVE_STATFS
+    struct statfs sfs;
 #endif
     storeAppendPrintf(sentry, "Store Directory Statistics:\n");
     storeAppendPrintf(sentry, "Store Entries          : %d\n",
@@ -610,18 +631,33 @@
 	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
+#if HAVE_STATVFS || HAVE_STATFS
 #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));
+#if HAVE_STATVFS
+	if (!statvfs(SD->path, &sfs))
+#elif HAVE_STATFS
+	if (!statfs(SD->path, &sfs))
+#endif
+	{
+#if HAVE_STATVFS
+	    /* Work around for Linux and others with no fragments.. */
+	    if (sfs.f_frsize == 0)
+		sfs.f_frsize = sfs.f_bsize;
+	    storeAppendPrintf(sentry, "Filesystem Space in use: %ld/%ld KB (%d%%)\n",
+		(long int)fsbtoblk((sfs.f_blocks - sfs.f_bavail), sfs.f_frsize, 1024),
+		(long int)fsbtoblk(sfs.f_blocks - sfs.f_bfree + sfs.f_bavail, sfs.f_frsize, 1024),
+		(int)percent(sfs.f_blocks - sfs.f_bfree, sfs.f_blocks - sfs.f_bfree + sfs.f_bavail));
+#elif HAVE_STATFS
+	    storeAppendPrintf(sentry, "Filesystem Space in use: %ld/%ld KB (%d%%)\n",
+		(long int)fsbtoblk((sfs.f_blocks - sfs.f_bfree), sfs.f_bsize, 1024),
+		(long int)fsbtoblk(sfs.f_blocks - sfs.f_bfree + sfs.f_bavail, sfs.f_bsize, 1024),
+		(int)percent(sfs.f_blocks - sfs.f_bfree, sfs.f_blocks - sfs.f_bfree + sfs.f_bavail));
+#endif
+	    storeAppendPrintf(sentry, "Filesystem Inodes in use: %ld/%ld (%d%%)\n",
+		(long int)sfs.f_files - sfs.f_ffree, (long int)sfs.f_files,
+		(int)percent(sfs.f_files - sfs.f_ffree, sfs.f_files));
 	}
 #endif
 	storeAppendPrintf(sentry, "Flags:");
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.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- squid/src/store_log.c	26 Jan 2000 03:21:47 -0000	1.1.1.1
+++ squid/src/store_log.c	4 Feb 2000 16:41:13 -0000	1.1.1.1.2.1
@@ -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.1.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 20    Storage Manager Logging Functions
  * AUTHOR: Duane Wessels
@@ -71,7 +71,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],
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/store_rebuild.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/store_rebuild.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 20    Store Rebuild Routines
  * AUTHOR: Duane Wessels
@@ -285,6 +285,7 @@
 		    storeDirMapBitReset(e->swap_file_number);
 		    e->swap_file_number = -1;
 		}
+		storeRelease(e);
 		RebuildState.objcount--;
 		RebuildState.cancelcount++;
 	    }
@@ -653,7 +654,7 @@
     valid_ctrl_t *ctrlp;
     char *path;
     struct stat *sb;
-#if !USE_ASYNC_IO
+#if !USE_ASYNC_IO_STAT
     int x;
 #endif
     assert(!EBIT_TEST(e->flags, ENTRY_VALIDATED));
@@ -669,7 +670,7 @@
     ctrlp->e = e;
     ctrlp->callback = callback;
     ctrlp->callback_data = callback_data;
-#if USE_ASYNC_IO
+#if USE_ASYNC_IO_STAT
     aioStat(path, sb, storeValidateComplete, ctrlp, tag);
 #else
     /*
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/structs.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/structs.h	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 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,6 +144,7 @@
     struct in_addr src_addr;
     struct in_addr dst_addr;
     struct in_addr my_addr;
+    int my_port;
     request_t *request;
 #if USE_IDENT
     ConnStateData *conn;	/* hack for ident */
@@ -183,6 +186,12 @@
     ushortlist *next;
 };
 
+struct _ipportlist {
+    u_short port;
+    struct in_addr addr;
+    ipportlist *next;
+};
+
 struct _relist {
     char *pattern;
     regex_t regex;
@@ -240,6 +249,7 @@
 	time_t read;
 	time_t lifetime;
 	time_t connect;
+	time_t peer_connect;
 	time_t request;
 	time_t pconn;
 	time_t siteSelect;
@@ -252,7 +262,7 @@
     } Timeout;
     size_t maxRequestSize;
     struct {
-	ushortlist *http;
+	ipportlist *http;
 	u_short icp;
 #if USE_HTCP
 	u_short htcp;
@@ -288,9 +298,11 @@
 	char *unlinkd;
     } Program;
     int dnsChildren;
+    int dnsRestart;
     int redirectChildren;
     int authenticateChildren;
     int authenticateTTL;
+    int authenticateIpTTL;
     struct {
 	char *host;
 	u_short port;
@@ -375,6 +387,7 @@
 	int redir_rewrites_host;
 	int persistent_client_posts;
 	int prefer_direct;
+	int nonhierarchical_direct;
 	int strip_query_terms;
     } onoff;
     acl *aclList;
@@ -440,6 +453,7 @@
 #endif
     HttpHeaderMask anonymize_headers;
     char *coredump_dir;
+    char *chroot_dir;
 };
 
 struct _SquidConfig2 {
@@ -711,6 +725,7 @@
     StoreEntry *entry;
     request_t *request;
     char *reply_hdr;
+    size_t reply_hdr_size;
     int reply_hdr_state;
     peer *peer;			/* peer request made to */
     int eof;			/* reached end-of-object? */
@@ -994,9 +1009,13 @@
 	int ignored_replies;
 	int n_keepalives_sent;
 	int n_keepalives_recv;
+	time_t probe_start;
 	time_t last_query;
 	time_t last_reply;
+	time_t last_connect_failure;
+	time_t last_connect_probe;
 	int logged_state;	/* so we can print dead/revived msgs */
+	int icp_last_reply_ok;  /* did it accept a request? */
     } stats;
     struct {
 	int version;
@@ -1029,6 +1048,7 @@
 #if DELAY_POOLS
 	unsigned int no_delay:1;
 #endif
+	unsigned int allow_miss:1;
     } options;
     int weight;
     struct {
@@ -1046,7 +1066,6 @@
     PeerDigest *digest;
 #endif
     int tcp_up;			/* 0 if a connect() fails */
-    time_t last_fail_time;
     struct in_addr addresses[10];
     int n_addresses;
     int rr_count;
@@ -1060,6 +1079,7 @@
     } carp;
 #endif
     char *login;		/* Proxy authorization */
+    time_t connect_timeout;
 };
 
 struct _net_db_name {
@@ -1304,12 +1324,14 @@
     int max_forwards;
     struct in_addr client_addr;
     struct in_addr my_addr;
+    int my_port;
     HttpHeader header;
     char *body;
     size_t body_sz;
     HierarchyLogEntry hier;
     err_type err_type;
     char *peer_login;		/* Configured peer login:password */
+    time_t lastmod;		/* Used on refreshes */
 };
 
 struct _cachemgr_passwd {
@@ -1364,11 +1386,11 @@
 	unsigned int flag_cbdata:1;
     } flags;
     struct {
+	wordlist *server_msg;
 	char *request;
 	char *reply;
     } ftp;
     char *request_hdrs;
-    wordlist *ftp_server_msg;
 };
 
 /*
@@ -1600,6 +1622,7 @@
     int n_tries;
     struct {
 	unsigned int dont_retry:1;
+	unsigned int ftp_pasv_failed:1;
     } flags;
 };
 
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/tools.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/tools.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -416,23 +416,39 @@
     if ((t = Config.visibleHostname) != NULL)
 	return t;
 
+    /* If tcp_incoming is set then try to get the corresponding hostname */
+    if (!present && Config.Addrs.tcp_incoming.s_addr != INADDR_ANY) {
+	host[0] = '\0';
+	if ((h = gethostbyaddr((char *)&Config.Addrs.tcp_incoming, sizeof(Config.Addrs.tcp_incoming), AF_INET)) != 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");
+	}
+    }
+    
     /* Get the host name and store it in host to return */
     if (!present) {
 	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 *
@@ -479,6 +495,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;
@@ -487,13 +504,20 @@
 	return;
     if ((pwd = getpwnam(Config.effectiveUser)) == NULL)
 	return;
+#if USE_ASYNC_IO
+    /* Flush any pending operations before switching user id */
+    aioSync();
+#endif
     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
@@ -513,6 +537,10 @@
 enter_suid(void)
 {
     debug(21, 3) ("enter_suid: PID %d taking root priveleges\n", getpid());
+#if USE_ASYNC_IO
+    /* Flush any pending operations before switching user id */
+    aioSync();
+#endif
 #if HAVE_SETRESUID
     setresuid(-1, 0, -1);
 #else
@@ -842,3 +870,14 @@
 {
     return (strcspn(s, w_space) != strlen(s));
 }
+
+int
+stringHasCntl(const unsigned char *s)
+{
+    char c;
+    while ((c = *s++) != '\0') {
+	if ( *s <= 0x1f )
+	    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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/typedefs.h	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/typedefs.h	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -69,6 +69,7 @@
 typedef struct _intlist intlist;
 typedef struct _intrange intrange;
 typedef struct _ushortlist ushortlist;
+typedef struct _ipportlist ipportlist;
 typedef struct _relist relist;
 typedef struct _SquidConfig SquidConfig;
 typedef struct _SquidConfig2 SquidConfig2;
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/unlinkd.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/unlinkd.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 12    Unlink Daemon
  * AUTHOR: Duane Wessels
@@ -48,6 +48,8 @@
     int x;
     setbuf(stdin, NULL);
     setbuf(stdout, NULL);
+    close(2);
+    open("/dev/null", O_RDWR);
     while (fgets(buf, UNLINK_BUF_LEN, stdin)) {
 	if ((t = strchr(buf, '\n')))
 	    *t = '\0';
@@ -167,12 +169,7 @@
     struct timeval slp;
     args[0] = "(unlinkd)";
     args[1] = NULL;
-#if HAVE_POLL && defined(_SQUID_OSF_)
-    /* pipes and poll() don't get along on DUNIX -DW */
-    x = ipcCreate(IPC_TCP_SOCKET,
-#else
-    x = ipcCreate(IPC_FIFO,
-#endif
+    x = ipcCreate(IPC_STREAM,
 	Config.Program.unlinkd,
 	args,
 	"unlinkd",
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/url.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/url.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 hno Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -44,7 +44,16 @@
     "HEAD",
     "CONNECT",
     "TRACE",
-    "PURGE"
+    "PURGE",
+    "OPTIONS",
+    "DELETE",
+    "PROPFIND",
+    "PROPPATCH",
+    "MKCOL",
+    "COPY",
+    "MOVE",
+    "LOCK",
+    "UNLOCK"
 };
 
 const char *ProtocolStr[] =
@@ -112,25 +121,36 @@
     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"));
+    assert(0 < matchDomainName("bfoo.com", "afoo.com"));
+    assert(0 > matchDomainName("afoo.com", "bfoo.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;
+    for (method = 0 ; method < METHOD_ENUM_END; method++) {
+	if (strcasecmp(s, RequestMethodStr[method])==0)
+	    return method;
     }
     return METHOD_NONE;
 }
@@ -144,8 +164,10 @@
 	return PROTO_HTTP;
     if (strcasecmp(s, "ftp") == 0)
 	return PROTO_FTP;
+#if 0
     if (strcasecmp(s, "https") == 0)
 	return PROTO_HTTPS;
+#endif
     if (strcasecmp(s, "file") == 0)
 	return PROTO_FTP;
     if (strcasecmp(s, "gopher") == 0)
@@ -263,7 +285,7 @@
 	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:
@@ -356,26 +378,78 @@
 	    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          NO
+ *  x.foo.com       foo.com          NO
+ *    foo.com      .foo.com         YES
+ *   .foo.com      .foo.com         YES
+ *  x.foo.com      .foo.com         YES
+ *
+ *  Return values:
+ *     0 means the host matches the domain
+ *    >0 means the host is greater than the domain
+ *    <0 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;
+    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
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.2.2.1
diff -u -r1.1.1.2 -r1.1.1.2.2.1
--- squid/src/urn.c	26 Jan 2000 03:23:10 -0000	1.1.1.2
+++ squid/src/urn.c	4 Feb 2000 16:41:13 -0000	1.1.1.2.2.1
@@ -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.2.2.1 2000/02/04 16:41:13 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) {