Improved patch for reading long ACL's from files

From: Arjan de Vet <[email protected]>
Date: Sat, 28 Sep 1996 23:45:07 +0200

In article <199609252025.WAA10200@adv.IAEhv.nl> I wrote:

>I've made a patch to read src and dst ACL's from a file (one entry per
>line), the new commands are 'acl <name> src_file <file>' and 'acl <name>
>dst_file <file>'.
>
>Furthermore I added a small patch to implement the ACL lookup speedup
>described above: a matched record in an ACL will be moved to the second
>position of the list (the first position is somewhat more difficult). This
[...]

I've made the patch more general. You can now use for any ACL the
following syntax:

        acl <aclname> <acltype> "file"

A file should contain one word (IP spec, domain name, regexp, etc.) per
line. Note that you can mix this new file method with the old method, e.g.:

        acl acl1 src 212.1.2.3/24 "/home/squid/etc/networks" 127.0.0.1

Furthermore the ACL speedup patch has been implemented for domain lists,
regex lists and int lists too.

The patch was made for 1.1beta4.

Arjan

-----------------------------------------------------------------------------
--- acl.c.orig Fri Sep 20 08:28:24 1996
+++ acl.c Sat Sep 28 23:11:31 1996
@@ -33,6 +33,10 @@
 /* Global */
 char *AclMatchedName = NULL;
 
+/* for reading ACL's from files */
+int aclFromFile = 0;
+FILE *aclFile;
+
 /* These three should never be referenced directly in this file! */
 struct _acl_deny_info_list *DenyInfoList = NULL;
 struct _acl_access *HTTPAccessList = NULL;
@@ -65,6 +69,44 @@
 static squid_acl aclType _PARAMS((char *s));
 static int decode_addr _PARAMS((char *, struct in_addr *, struct in_addr *));
 
+char *
+strtokFile(void)
+{
+ char *t, *fn;
+ LOCAL_ARRAY(char, buf, 256);
+
+strtok_again:
+ if (!aclFromFile) {
+ t = (strtok(NULL, w_space));
+ if (t && (*t == '\"' || *t == '\'')) {
+ /* quote found, start reading from file */
+ fn = ++t;
+ while (*t && *t != '\"' && *t != '\'') t++;
+ *t = '\0';
+ if ((aclFile = fopen(fn, "r")) == NULL) {
+ debug(28, 0, "strtokFile: %s not found\n", fn);
+ return(NULL);
+ }
+ aclFromFile = 1;
+ } else {
+ return(t);
+ }
+ }
+ /* aclFromFile */
+ if (fgets(buf, 256, aclFile) == NULL) {
+ /* stop reading from file */
+ fclose(aclFile);
+ aclFromFile = 0;
+ goto strtok_again;
+ } else {
+ t = buf;
+ /* skip leading and trailing white space */
+ t += strspn(buf, w_space);
+ t[strcspn(t, w_space)] = '\0';
+ return(t);
+ }
+}
+
 static squid_acl
 aclType(char *s)
 {
@@ -115,7 +157,7 @@
     intlist **Tail = &head;
     intlist *q = NULL;
     char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         q = xcalloc(1, sizeof(intlist));
         q->i = atoi(t);
         *(Tail) = q;
@@ -131,7 +173,7 @@
     intlist **Tail = &head;
     intlist *q = NULL;
     char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         q = xcalloc(1, sizeof(intlist));
         q->i = (int) urlParseProtocol(t);
         *(Tail) = q;
@@ -147,7 +189,7 @@
     intlist **Tail = &head;
     intlist *q = NULL;
     char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         q = xcalloc(1, sizeof(intlist));
         q->i = (int) urlParseMethod(t);
         *(Tail) = q;
@@ -223,7 +265,7 @@
     LOCAL_ARRAY(char, addr2, 256);
     LOCAL_ARRAY(char, mask, 256);
 
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         q = xcalloc(1, sizeof(struct _acl_ip_data));
         if (!strcasecmp(t, "all")) {
             q->addr1.s_addr = 0;
@@ -286,7 +328,7 @@
     char *t = NULL;
 
     data = xcalloc(1, sizeof(struct _acl_time_data));
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         if (*t < '0' || *t > '9') {
             /* assume its day-of-week spec */
             while (*t) {
@@ -360,7 +402,7 @@
     relist *q = NULL;
     char *t = NULL;
     regex_t comp;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         if (regcomp(&comp, t, REG_EXTENDED) != REG_NOERROR) {
             debug(28, 0, "%s line %d: %s\n",
                 cfg_filename, config_lineno, config_input_line);
@@ -383,7 +425,7 @@
     wordlist **Tail = &head;
     wordlist *q = NULL;
     char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         q = xcalloc(1, sizeof(wordlist));
         q->key = xstrdup(t);
         *(Tail) = q;
@@ -399,7 +441,7 @@
     wordlist **Tail = &head;
     wordlist *q = NULL;
     char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
         Tolower(t);
         q = xcalloc(1, sizeof(wordlist));
         q->key = xstrdup(t);
@@ -630,7 +672,10 @@
 {
     struct in_addr h;
     unsigned long lh, la1, la2;
+ struct _acl_ip_data *first, *prev;
 
+ first = data; /* remember first element, this will never be moved */
+ prev = NULL; /* previous element in the list */
     while (data) {
         h.s_addr = c.s_addr & data->mask.s_addr;
         debug(28, 3, "aclMatchIp: h = %s\n", inet_ntoa(h));
@@ -639,6 +684,13 @@
         if (!data->addr2.s_addr) {
             if (h.s_addr == data->addr1.s_addr) {
                 debug(28, 3, "aclMatchIp: returning 1\n");
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
                 return 1;
             }
         } else {
@@ -651,6 +703,7 @@
                 return 1;
             }
         }
+ prev = data;
         data = data->next;
     }
     debug(28, 3, "aclMatchIp: returning 0\n");
@@ -660,27 +713,52 @@
 static int
 aclMatchDomainList(wordlist * data, char *host)
 {
+ wordlist *first, *prev;
+
     if (host == NULL)
         return 0;
     debug(28, 3, "aclMatchDomainList: checking '%s'\n", host);
+ first = data;
+ prev = NULL;
     for (; data; data = data->next) {
         debug(28, 3, "aclMatchDomainList: looking for '%s'\n", data->key);
- if (matchDomainName(data->key, host))
+ if (matchDomainName(data->key, host)) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
             return 1;
     }
+ prev = data;
+ }
     return 0;
 }
 
 static int
 aclMatchRegex(relist * data, char *word)
 {
+ relist *first, *prev;
     if (word == NULL)
         return 0;
     debug(28, 3, "aclMatchRegex: checking '%s'\n", word);
+ first = data;
+ prev = NULL;
     while (data) {
         debug(28, 3, "aclMatchRegex: looking for '%s'\n", data->pattern);
- if (regexec(&data->regex, word, 0, 0, 0) == 0)
+ if (regexec(&data->regex, word, 0, 0, 0) == 0) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
             return 1;
+ }
+ prev = data;
         data = data->next;
     }
     return 0;
@@ -689,9 +767,21 @@
 static int
 aclMatchInteger(intlist * data, int i)
 {
+ intlist *first, *prev;
+ first = data;
+ prev = NULL;
     while (data) {
- if (data->i == i)
+ if (data->i == i) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
             return 1;
+ }
+ prev = data;
         data = data->next;
     }
     return 0;
--- squid.conf.pre.in.orig Thu Sep 26 21:19:21 1996
+++ squid.conf.pre.in Sat Sep 28 22:15:47 1996
@@ -637,12 +637,15 @@
 # Defining an Access List
 #
 # acl aclname acltype string1 ...
+# acl aclname acltype "file" ...
 #
-# acltype is one of src dst srcdomain dstdomain url_pattern urlpath_pattern
+# when using "file", the file should contain one item per line
+#
+# acltype is one of src dst srcdomain dstdomain url_regex urlpath_regex
 # time port proto method
 #
 # acl aclname src ip-address/netmask ... (clients IP address)
-# acl aclname src addr1/mask1-addr2/mask2 ... (range of addresses)
+# acl aclname src addr1-addr2/mask2 ... (range of addresses)
 # acl aclname dst ip-address/netmask ... (URL host's IP address)
 # acl aclname srcdomain foo.com ... (taken from reverse DNS lookup)
 # acl aclname dstdomain foo.com ... (taken from the URL)
Received on Sat Sep 28 1996 - 15:15:08 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:33:05 MST