Execute a shell-script to search

Nathan Torkington (Nathan.Torkington@vuw.ac.nz)
Mon, 19 Jul 1993 14:15:55 +1200


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;
}