diff -C 5 server/Makefile.in server.black/Makefile.in
*** server/Makefile.in	Fri Dec 15 13:12:10 1995
--- server.black/Makefile.in	Wed Dec 20 16:26:36 1995
***************
*** 55,65 ****
  CLIENT_LIBS	= -lutil $(XTRA_LIBS)
  
  PROGS		= cached 
  UTILS		= client dnsserver
  CGIPROGS	= cachemgr.cgi
! OBJS	 	= comm.o cache_cf.o debug.o disk.o dynamic_array.o \
  		  fdstat.o filemap.o ftp.o gopher.o hash.o \
  		  http.o icp.o ipcache.o mime.o neighbors.o objcache.o \
  		  proto.o stack.o stat.o stmem.o store.o storetoString.o \
  		  tools.o ttl.o url.o wais.o $(XTRA_OBJS)
  
--- 55,65 ----
  CLIENT_LIBS	= -lutil $(XTRA_LIBS)
  
  PROGS		= cached 
  UTILS		= client dnsserver
  CGIPROGS	= cachemgr.cgi
! OBJS	 	= block.c comm.o cache_cf.o debug.o disk.o dynamic_array.o \
  		  fdstat.o filemap.o ftp.o gopher.o hash.o \
  		  http.o icp.o ipcache.o mime.o neighbors.o objcache.o \
  		  proto.o stack.o stat.o stmem.o store.o storetoString.o \
  		  tools.o ttl.o url.o wais.o $(XTRA_OBJS)
  
Only in server.black: block.c
diff -C 5 server/cache_cf.c server.black/cache_cf.c
*** server/cache_cf.c	Sat Dec 16 20:45:28 1995
--- server.black/cache_cf.c	Thu Dec 21 11:39:48 1995
***************
*** 960,969 ****
--- 960,979 ----
  	self_destruct(line_in);
      debug(1, "parseBindAddressLine: adding %s\n", token);
      addToStopList(&bind_addr_list, token);
  }
  
+ void parseBlockListLine(line_in)
+      char *line_in;
+ {
+     char *token;
+     token = strtok(NULL, w_space);
+     if (token == (char *) NULL)
+       return;
+     blockAddToList(token);
+ }
+ 
  void parseLocalDomainLine(line_in)
       char *line_in;
  {
      char *token;
      while ((token = strtok(NULL, w_space))) {
***************
*** 1232,1241 ****
--- 1242,1255 ----
  	else if (!strcmp(token, "ftp"))
  	    parseFtpLine(line_in);
  
  	else if (!strcmp(token, "ttl_pattern"))
  	    parseTTLPattern(line_in);
+ 
+         /* Parse a blocklist line */
+         else if (!strcmp(token, "blocklist"))
+           parseBlockListLine(line_in);
  
  	/* Parse a negative_ttl line */
  	else if (!strcmp(token, "negative_ttl"))
  	    parseNegativeLine(line_in);
  
diff -C 5 server/icp.c server.black/icp.c
*** server/icp.c	Sat Dec 16 20:45:43 1995
--- server.black/icp.c	Thu Dec 21 11:17:53 1995
***************
*** 1516,1525 ****
--- 1516,1549 ----
  		30,
  		icpSendERRORComplete,
  		astm);
  	    /* icpSendERRORComplete() will close the FD and deallocate astm */
  	    safe_free(orig_url_ptr);
+       } else if( blockCheck( astm->url ) ) {
+ 	  CacheInfo->log_append(CacheInfo,    /* TCP_BLOCK */
+ 	      astm->url,
+ 	      inet_ntoa(astm->peer.sin_addr),
+ 	      0,
+ 	      "TCP_BLOCK",
+ 	      astm->type );
+ 	  sprintf(tmp_error_buf, CACHED_RETRIEVE_ERROR_MSG,
+ 	      astm->url,
+ 	      astm->url,
+ 	      "authorization",
+ 	      123,
+ 	      "Not authorized",
+ 	      "Your request is not authorized.",
+ 	      HARVEST_VERSION,
+ 	      comm_hostname());
+ 	  icpWrite(fd,
+ 	      xstrdup(tmp_error_buf),
+ 	      strlen(tmp_error_buf),
+ 	      30,
+ 	      icpSendERRORComplete,
+ 	      astm);
+ 	  /* icpSendERRORComplete() will close the FD and deallocate astm */
+ 	  safe_free(orig_url_ptr);
  	} else if (second_ip_acl_check(fd, astm) == IP_DENY) {
  	    CacheInfo->log_append(CacheInfo,	/* TCP_DENIED */
  		astm->url,
  		inet_ntoa(astm->peer.sin_addr),
  		0,
/*
 *  File:         block.c
 *  Description:  Blacklisting specific URLs
 *  Author:       Duane Wessels, CU Boulder & Daniel O'Callaghan, U of Melbourne
 *  Created:      Fri Dec 15 1995
 *  Language:     C
 *
 **********************************************************************
 *  Copyright (c) 1994, 1995.  All rights reserved.
 *  
 *    The Harvest software was developed by the Internet Research Task
 *    Force Research Group on Resource Discovery (IRTF-RD):
 *  
 *          Mic Bowman of Transarc Corporation.
 *          Peter Danzig of the University of Southern California.
 *          Darren R. Hardy of the University of Colorado at Boulder.
 *          Udi Manber of the University of Arizona.
 *          Michael F. Schwartz of the University of Colorado at Boulder.
 *          Duane Wessels of the University of Colorado at Boulder.
 *  
 *    This copyright notice applies to software in the Harvest
 *    ``src/'' directory only.  Users should consult the individual
 *    copyright notices in the ``components/'' subdirectories for
 *    copyright information about other software bundled with the
 *    Harvest source code distribution.
 *  
 *  TERMS OF USE
 *    
 *    The Harvest software may be used and re-distributed without
 *    charge, provided that the software origin and research team are
 *    cited in any use of the system.  Most commonly this is
 *    accomplished by including a link to the Harvest Home Page
 *    (http://harvest.cs.colorado.edu/) from the query page of any
 *    Broker you deploy, as well as in the query result pages.  These
 *    links are generated automatically by the standard Broker
 *    software distribution.
 *    
 *    The Harvest software is provided ``as is'', without express or
 *    implied warranty, and with no support nor obligation to assist
 *    in its use, correction, modification or enhancement.  We assume
 *    no liability with respect to the infringement of copyrights,
 *    trade secrets, or any patents, and are not responsible for
 *    consequential damages.  Proper use of the Harvest software is
 *    entirely the responsibility of the user.
 *  
 *  DERIVATIVE WORKS
 *  
 *    Users may make derivative works from the Harvest software, subject 
 *    to the following constraints:
 *  
 *      - You must include the above copyright notice and these 
 *        accompanying paragraphs in all forms of derivative works, 
 *        and any documentation and other materials related to such 
 *        distribution and use acknowledge that the software was 
 *        developed at the above institutions.
 *  
 *      - You must notify IRTF-RD regarding your distribution of 
 *        the derivative work.
 *  
 *      - You must clearly notify users that your are distributing 
 *        a modified version and not the original Harvest software.
 *  
 *      - Any derivative product is also subject to these copyright 
 *        and use restrictions.
 *  
 *    Note that the Harvest software is NOT in the public domain.  We
 *    retain copyright, as specified above.
 *  
 *  HISTORY OF FREE SOFTWARE STATUS
 *  
 *    Originally we required sites to license the software in cases
 *    where they were going to build commercial products/services
 *    around Harvest.  In June 1995 we changed this policy.  We now
 *    allow people to use the core Harvest software (the code found in
 *    the Harvest ``src/'' directory) for free.  We made this change
 *    in the interest of encouraging the widest possible deployment of
 *    the technology.  The Harvest software is really a reference
 *    implementation of a set of protocols and formats, some of which
 *    we intend to standardize.  We encourage commercial
 *    re-implementations of code complying to this set of standards.  
 *  
 *  
 */

#ifndef USE_POSIX_REGEX
#define USE_POSIX_REGEX		/* put before includes; always use POSIX */
#endif

#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <memory.h>

#include "config.h"
#include "autoconf.h"
#include "GNUregex.h"
#include "debug.h"
#include "store.h"
#include "cache_cf.h"
#include "util.h"

typedef struct _blocklist {
    char *pattern;
    regex_t compiled_pattern;
    struct _blocklist *next;
} blocklist;

static blocklist *BLOCK_tbl = NULL;
static blocklist *BLOCK_tail = NULL;

#define BLOCK_MATCHED 1

void blockAddToList(pattern)
     char *pattern;
{
    blocklist *t;
    regex_t comp;

    if (regcomp(&comp, pattern, REG_EXTENDED) != REG_NOERROR) {
	debug(0, "blockAddToList: Invalid regular expression: %s\n",
	    pattern);
	return;
    }

    t = (blocklist *) xmalloc(sizeof(blocklist));
    memset((char *) t, '\0', sizeof(blocklist));

    t->pattern = (char *) xstrdup(pattern);
    t->compiled_pattern = comp;
    t->next = (blocklist *) NULL;

    if (!BLOCK_tbl)
	BLOCK_tbl = t;
    if (BLOCK_tail)
	BLOCK_tail->next = t;
    BLOCK_tail = t;
}


int blockCheck(url)
     char *url;
{
    char buf[301];
    blocklist *t;
    blocklist *match;
    double d;
    int flags = 0;

    debug(5, "blockCheck: Checking blocklist for %s\n", url);

    match = (blocklist *) NULL;
    for (t = BLOCK_tbl; t; t = t->next) {
	if (regexec(&(t->compiled_pattern), url, 0, 0, 0) == 0) {
	    match = t;
	    debug(5, "blockCheck: Matched '%s'\n",
		match->pattern);
	    flags |= BLOCK_MATCHED;
	}
    }

    return flags;
}
