Index: include/splay.h
===================================================================
RCS file: /cvsroot/squid/squid/include/splay.h,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 splay.h
--- include/splay.h	2000/04/20 21:57:34	1.1.1.5
+++ include/splay.h	2000/10/17 09:15:33
@@ -2,6 +2,8 @@
  * $Id: splay.h,v 1.1.1.5 2000/04/20 21:57:34 hno Exp $
  */
 
+#ifndef _SPLAY_H
+#define _SPLAY_H
 
 typedef struct _splay_node {
     void *data;
@@ -19,3 +21,5 @@
 extern splayNode *splay_splay(const void *, splayNode *, SPLAYCMP *);
 extern void splay_destroy(splayNode *, SPLAYFREE *);
 extern void splay_walk(splayNode *, SPLAYWALKEE *, void *);
+
+#endif /* _SPLAY_H */
Index: src/acl.c
===================================================================
RCS file: /cvsroot/squid/squid/src/acl.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 acl.c
--- src/acl.c	2000/04/20 21:57:34	1.1.1.6
+++ src/acl.c	2000/10/17 09:15:34
@@ -41,6 +41,7 @@
 static hash_table *proxy_auth_cache = NULL;
 
 static void aclParseDomainList(void *curlist);
+static void aclParseProxyAuthList(void **current);
 static void aclParseIpList(void *curlist);
 static void aclParseIntlist(void *curlist);
 static void aclParseWordList(void *curlist);
@@ -57,7 +58,7 @@
 static int aclMatchAcl(struct _acl *, aclCheck_t *);
 static int aclMatchIntegerRange(intrange * data, int i);
 static int aclMatchTime(acl_time_data * data, time_t when);
-static int aclMatchUser(wordlist * data, const char *ident);
+static int aclMatchUser(void *proxyauth_acl, char *user);
 static int aclMatchIp(void *dataptr, struct in_addr c);
 static int aclMatchDomainList(void *dataptr, const char *);
 static int aclMatchIntegerRange(intrange * data, int i);
@@ -618,6 +619,45 @@
 	wordlistAdd(curlist, t);
 }
 
+static void
+aclParseProxyAuthList(void ** current)
+{
+  char *t=NULL;
+  acl_proxy_auth_data **data=(acl_proxy_auth_data **)current;
+  splayNode *Top=NULL;
+  int case_insensitive;
+  
+  debug(28,2) ("aclParseProxyAuthList: parsing authlist\n");
+  if (*data==NULL) {
+    debug(28,3)("aclParseProxyAuthList: current is null. Creating\n");
+    *data=memAllocate(MEM_ACL_PROXY_AUTH_DATA); /*we rely on mA. zeroing*/
+  }
+	
+  if ((t = strtokFile())) {
+    debug(28,5)("aclParseProxyAuthList: First token is %s\n",t);
+    if (!strcmp("-i",t)) {
+      debug(28,5)("aclParseProxyAuthList: Going case-insensitive\n");
+      (*data)->flags|=PROXY_AUTH_IS_CASE_INSENSITIVE;
+    }
+    else
+      Top=splay_insert(xstrdup(t), Top, (SPLAYCMP *)strcmp);
+  }
+  
+  case_insensitive=(*data)->flags & PROXY_AUTH_IS_CASE_INSENSITIVE;
+  debug(28,3)("aclParseProxyAuthList: Case-insensitive-switch is %d\n",
+              case_insensitive);
+  /* we might inherit from a previous declaration */
+	
+  debug(28,4) ("aclParseProxyAuthList: parsing proxy-auth list\n");
+  while ((t = strtokFile())) {
+    debug(28,6)("aclParseProxyAuthList: Got token: %s\n",t);
+    if (case_insensitive) Tolower(t);
+    Top=splay_insert(xstrdup(t), Top, (SPLAYCMP *)strcmp);
+  }
+  (*data)->names=Top;
+}
+
+
 /**********************/
 /* aclParseDomainList */
 /**********************/
@@ -726,7 +766,7 @@
 	aclParseMethodList(&A->data);
 	break;
     case ACL_PROXY_AUTH:
-	aclParseWordList(&A->data);
+			aclParseProxyAuthList(&A->data);
 	if (!proxy_auth_cache) {
 	    /* First time around, 7921 should be big enough */
 	    proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string);
@@ -980,20 +1020,29 @@
 }
 
 static int
-aclMatchUser(wordlist * data, const char *user)
+aclMatchUser(void * proxyauth_acl, char *user)
 {
-    if (user == NULL)
-	return 0;
-    debug(28, 3) ("aclMatchUser: checking '%s'\n", user);
-    while (data) {
-	debug(28, 3) ("aclMatchUser: looking for '%s'\n", data->key);
-	if (strcmp(data->key, "REQUIRED") == 0 && *user != '\0' && strcmp(user, "-") != 0)
-	    return 1;
-	if (strcmp(data->key, user) == 0)
-	    return 1;
-	data = data->next;
-    }
-    return 0;
+	acl_proxy_auth_data *data=(acl_proxy_auth_data *)proxyauth_acl;
+	splayNode *Top=data->names;
+	int case_insensitive=((data->flags&PROXY_AUTH_IS_CASE_INSENSITIVE) != 0);
+	
+	debug(28,7)("aclMatchUser: user is %s, case_insensitive is %d\n",
+							user,case_insensitive);
+	debug(28,8)("Top is %p, Top->data is %s\n",Top,
+							(Top!=NULL?(Top)->data:"Unavailable"));
+	
+	if (user==NULL)
+		return 0;
+	if (case_insensitive)
+		Tolower(user);
+	
+	Top=splay_splay(user,Top,(SPLAYCMP *)strcmp);
+	/* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */
+	debug(28,7)("aclMatchUser: returning %d,Top is %p, Top->data is %s\n",
+							!splayLastResult,
+							Top, (Top?Top->data:"Unavailable"));
+	data->names=Top;
+	return !splayLastResult;
 }
 
 static int
@@ -1809,6 +1858,13 @@
     memFree(p, MEM_ACL_IP_DATA);
 }
 
+static void aclFreeProxyAuthData(void *data) {
+  acl_proxy_auth_data *d=data;
+  splay_destroy(d->names,xfree);
+  memFree(d,MEM_ACL_PROXY_AUTH_DATA);
+}
+
+
 void
 aclDestroyAcls(acl ** head)
 {
@@ -1830,12 +1886,16 @@
 	    break;
 #if SQUID_SNMP
 	case ACL_SNMP_COMMUNITY:
+		wordlistDestroy((wordlist **) & a->data);
+		break;
 #endif
 #if USE_IDENT
 	case ACL_IDENT:
+		wordlistDestroy((wordlist **) & a->data);
+		break;
 #endif
 	case ACL_PROXY_AUTH:
-	    wordlistDestroy((wordlist **) & a->data);
+	    aclFreeProxyAuthData(a->data);
 	    break;
 	case ACL_TIME:
 	    aclDestroyTimeList(a->data);
@@ -2022,6 +2082,25 @@
 }
 
 static void
+aclDumpProxyAuthListWalkee(void *node_data, void * outlist) {
+	/* outlist is really a wordlist ** */
+	wordlistAdd(outlist,node_data);
+}
+
+wordlist *
+aclDumpProxyAuthList (acl_proxy_auth_data * data) {
+	wordlist *wl = NULL;
+	if ((data->flags&PROXY_AUTH_IS_CASE_INSENSITIVE) != 0)
+		wordlistAdd(&wl,"-i");
+	/* damn this is VERY inefficient for long ACL lists... filling
+		 a wordlist this way costs Sum(1,N) iterations. For instance
+		 a 1000-elements list woll be filled in 499500 iterations.
+	*/
+	splay_walk(data->names,aclDumpProxyAuthListWalkee,&wl);
+	return wl;
+}
+
+static void
 aclDumpIpListWalkee(void *node, void *state)
 {
     acl_ip_data *ip = node;
@@ -2162,13 +2241,17 @@
 	break;
 #if SQUID_SNMP
     case ACL_SNMP_COMMUNITY:
+			return wordlistDup(a->data);
+			break;
 #endif
 #if USE_IDENT
     case ACL_IDENT:
+			return wordlistDup(a->data);
+			break;
 #endif
     case ACL_PROXY_AUTH:
-	return wordlistDup(a->data);
-	break;
+			return aclDumpProxyAuthList(a->data);
+			break;
     case ACL_TIME:
 	return aclDumpTimeSpecList(a->data);
 	break;
Index: src/enums.h
===================================================================
RCS file: /cvsroot/squid/squid/src/enums.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 enums.h
--- src/enums.h	2000/04/20 21:57:34	1.1.1.6
+++ src/enums.h	2000/10/17 09:15:34
@@ -498,6 +498,7 @@
     MEM_ACL_IP_DATA,
     MEM_ACL_LIST,
     MEM_ACL_NAME_LIST,
+	MEM_ACL_PROXY_AUTH_DATA,
     MEM_ACL_PROXY_AUTH_USER,
     MEM_ACL_TIME_DATA,
     MEM_AIO_RESULT_T,
Index: src/mem.c
===================================================================
RCS file: /cvsroot/squid/squid/src/mem.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 mem.c
--- src/mem.c	2000/04/20 21:57:34	1.1.1.5
+++ src/mem.c	2000/10/17 09:15:34
@@ -201,6 +201,8 @@
     memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0);
     memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0);
     memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0);
+    memDataInit(MEM_ACL_PROXY_AUTH_DATA, "acl_proxy_auth_data",
+        sizeof(acl_proxy_auth_data), 0);
     memDataInit(MEM_ACL_PROXY_AUTH_USER, "acl_proxy_auth_user",
 	sizeof(acl_proxy_auth_user), 0);
     memDataInit(MEM_AIO_RESULT_T, "aio_result_t", sizeof(aio_result_t), 0);
Index: src/structs.h
===================================================================
RCS file: /cvsroot/squid/squid/src/structs.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 structs.h
--- src/structs.h	2000/04/20 21:57:35	1.1.1.6
+++ src/structs.h	2000/10/17 09:15:34
@@ -31,6 +31,9 @@
  *
  */
 
+#include "config.h"
+#include "splay.h"
+
 struct _dlink_node {
     void *data;
     dlink_node *prev;
@@ -41,6 +44,15 @@
     dlink_node *head;
     dlink_node *tail;
 };
+
+#define PROXY_AUTH_IS_CASE_INSENSITIVE 0x1
+/* FIXME: not yet imlemented */ 
+#define PROXY_AUTH_IS_REQUIRED 0x2
+struct _acl_proxy_auth_data {
+    u_num32 flags;
+    splayNode *names;
+};
+
 
 struct _acl_ip_data {
     struct in_addr addr1;	/* if addr2 non-zero then its a range */
Index: src/typedefs.h
===================================================================
RCS file: /cvsroot/squid/squid/src/typedefs.h,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 typedefs.h
--- src/typedefs.h	2000/04/20 21:57:35	1.1.1.6
+++ src/typedefs.h	2000/10/17 09:15:35
@@ -61,6 +61,7 @@
 typedef struct _acl_name_list acl_name_list;
 typedef struct _acl_deny_info_list acl_deny_info_list;
 typedef struct _acl_proxy_auth acl_proxy_auth;
+typedef struct _acl_proxy_auth_data acl_proxy_auth_data;
 typedef struct _acl_proxy_auth_user acl_proxy_auth_user;
 typedef struct _acl_arp_data acl_arp_data;
 typedef struct _acl acl;

