Execute a shell-script to search

Nathan Torkington <Nathan.Torkington@vuw.ac.nz>
Date: Mon, 19 Jul 1993 14:15:55 +1200
From: Nathan Torkington <Nathan.Torkington@vuw.ac.nz>
Message-id: <199307190215.AA17792@kauri.vuw.ac.nz>
To: www-talk@nxoc01.cern.ch
Subject: Execute a shell-script to search
Status: RO
I've taken the standard CERN (2.06) daemon and added an executable
shell script ability to it.  What it now does, when it is given
keywords on a URL like http://host/path/file is:

 -- expand /path/file using the rules file, giving a filename
 -- look for filename.search
 -- if it exists, execute it with the search keywords as arguments
    -- whatever this returns is passed back to the client verbatim
 -- if it doesn't exist, fail

This has enabled me to put in my home.html file,
	<ISINDEX>
and make a file called home.html.search that contains

	#!/bin/sh
	ARGS=`echo "$*" | /bin/sed 's/ /\?/g'`
	/usr/local/bin/www -source "wais://wais.vuw.ac.nz:90210/this-server?$ARGS"
	exit 0

thus enabling users to search the home-page directly, and get the
results of a WAIS search back.

Sexy, eh?  Diffs follow.

Cheers;

Nat

*** Daemon/Implementation/HTRetrieve.c	Thu May 27 03:16:34 1993
--- gnatDaemon/Implementation/HTRetrieve.c	Mon Jul 19 13:57:38 1993
***************
*** 24,29 ****
--- 24,33 ----
  #define BUFFER_SIZE 4096	/* Arbitrary size for efficiency */
  #define INFINITY 512		/* file name length @@ FIXME */
  
+ #include <sys/stat.h>
+ #include <assert.h>
+ #include <sys/types.h>
+ 
  #include "HTUtils.h"
  #include "HTFormat.h"
  #include "tcp.h"
***************
*** 92,133 ****
      int soc;
  #endif
  {
! 
!     char * arg2 = 0;	/* Simplified argument */
!     char * keywords=strchr(arg, '?');
      
! #ifdef NOSEARCH
      if (keywords) {
! 	*keywords++ = 0;		/* Chop keywords off */
! 	if (!*keywords) keywords = NULL;
! 	else {
! 	    char *p;
! 	    for (p=keywords; *p; p++) if (*p == '+') *p = ' ';
! 	    /* Plusses to spaces */
! 	    HTUnEscape(keywords);
  	}
      }
-     
-     if (keywords) {
- 	if (TRACE) printf("HTHandle: can't perform search %s\n",
- 		arg);
- 	return HTLoadError(HTASCIIWriter(soc), 403,
- 	    "Sorry, this server does not perform searches.");
- 	    /* It ought to, using an executable script */
-     }
- #endif
  
-     StrAllocCopy(arg2, arg);
-     HTSimplify(arg2);	/* Remove ".." etc  (DMX) */
  
  
  /*		Load the document into the client
  */
!     {
  	HTStream * client = HTASCIIWriter(soc);
  
  	HTLoadToStream(arg2, NO, client);
! 	free(arg2);
  	return HT_LOADED;
      }
  
--- 96,199 ----
      int soc;
  #endif
  {
!     char *myarg = NULL;
!     char * arg2=NULL;	/* Simplified argument */
!     char *keywords=NULL;
!     char *ptr, *ptr2;
!     int i;
      
!     StrAllocCopy(myarg, arg);
! 
!     for (ptr = myarg; *ptr && (*ptr != '?'); ptr++) ;
!     if (*ptr == '?') {
!       StrAllocCopy(keywords, ptr+1);
!       *ptr = '\0';
!       ptr=keywords;
!       while (*ptr) {
! 	if (*ptr == '?')
! 	  *ptr = ' ';
! 	ptr++;
!       }
! 
!     }
! 
!     HTSimplify(myarg);	/* Remove ".." etc  (DMX) */
!     ptr = HTStrip(myarg);
!     StrAllocCopy(arg2, ptr);
!     free(myarg);
! 
      if (keywords) {
!       /* test if a shell script equal to <path>.search exists */
!       char *newfname = NULL;
!       char *expanded = NULL;
!       char *fulladdr = NULL;
! 
!       struct stat sbuf;
!       FILE *pfp;
!       int total=0;
!       int i;
!       
!       expanded = HTTranslate(arg2);
!       free(arg2);
!       if (!expanded) {
! 	free(keywords);
! 	return HTLoadError(HTASCIIWriter(soc), 666, "Can't translate to physical address.");
!       }
! 
!       fulladdr = HTParse(expanded, "", PARSE_PATH|PARSE_PUNCTUATION);
!       free(expanded);
!       if (!fulladdr) {
! 	free(keywords);
! 	return HTLoadError(HTASCIIWriter(soc), 666, "Can't translate to physical address.");
!       }
! 
!       total = (2 + strlen(keywords) + strlen(".search") + strlen(fulladdr));
!       newfname = malloc(sizeof(char) * total);
!       
!       if (!newfname) {
! 	free(fulladdr);
! 	free(keywords);
! 	return HTLoadError(HTASCIIWriter(soc), 666, "Memory error.");
!       }
!       sprintf(newfname, "%s.search", fulladdr);
!       if (-1 == stat(newfname, &sbuf)) {
! 	free(fulladdr);
! 	free(keywords);
! 	return HTLoadError(HTASCIIWriter(soc), 666, "This page cannot be searched.");
!       }
!       
!       strcat(newfname, " ");
!       strcat(newfname, keywords);
!       
!       /* execute and send results to client */
!       {
! 	char buf[BUFFER_SIZE];
! 	int n;
! 
! 	pfp=popen(newfname, "r");
! 	if (!pfp) {
! 	  free(fulladdr);
! 	  free(keywords);
! 	  return HTLoadError(HTASCIIWriter(soc), 666, "Couldn't execute the search program.");
  	}
+ 	while (n = fread(buf, sizeof(char), BUFFER_SIZE, pfp))
+ 	  write(soc, buf, n);
+       }	
+       pclose(pfp);
+       free(fulladdr);
+       free(keywords);
+       return HT_LOADED;
      }
  
  
  
  /*		Load the document into the client
  */
!       {
  	HTStream * client = HTASCIIWriter(soc);
  
  	HTLoadToStream(arg2, NO, client);
! 	free(keywords);
  	return HT_LOADED;
      }