*** /tmp/hardy/wais-8-b5.1/ir/ir.c	Thu Aug 27 12:27:50 1992
--- ir/ir.c	Mon Jan 18 14:33:11 1993
***************
*** 6,11 ****
--- 6,14 ----
  
  /* Change log:
   * $Log:	ir.c,v $
+  * Revision 1.50  93/01/18  14:32:36  hardy
+  * Dynamic WAIS support.
+  *
   * Revision 1.49  92/05/10  14:43:35  jonathan
   * Made a little safer on NULL docid's when parsing.
   * 
***************
*** 70,76 ****
  */
  
  #ifndef lint
! static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/ir/RCS/ir.c,v 1.49 92/05/10 14:43:35 jonathan Exp $";
  #endif
  
  /*----------------------------------------------------------------------*/
--- 73,79 ----
  */
  
  #ifndef lint
! static char *RCSid = "$Header: /tmp_mnt/home/burton/hardy/ds/proj/wais/wais-8-b5/ir/RCS/ir.c,v 1.3 92/10/29 21:32:21 hardy Exp Locker: hardy $";
  #endif
  
  /*----------------------------------------------------------------------*/
***************
*** 181,191 ****
  
  #ifdef Mach
  #include <sys/inode.h>
! #define S_ISDIR(f_mode) ((f_mode) & IFDIR)
  #endif /* Mach */
  
  #if (defined(NeXT) && !(defined(S_ISDIR)))
! #define S_ISDIR(f_mode) ((f_mode) & S_IFDIR)
  #endif
  
  /*----------------------------------------------------------------------*/
--- 184,194 ----
  
  #ifdef Mach
  #include <sys/inode.h>
! #define S_ISDIR(f_mode) (f_mode & IFDIR)
  #endif /* Mach */
  
  #if (defined(NeXT) && !(defined(S_ISDIR)))
! #define S_ISDIR(f_mode) ((fmode) & S_IFDIR)
  #endif
  
  /*----------------------------------------------------------------------*/
***************
*** 786,794 ****
    else
     { /* run the search on the database.  If a new
  	search engine were to be used, this is where it would be hooked in */
!      search_status = run_search(aSearch, headers,&diags, index_directory, 
! 				&seed_words_used, waisProtocolVersion,
! 				&headerNum);
     }
  
  #define CATALOG_FOR_NO_RESULTS
--- 789,805 ----
    else
     { /* run the search on the database.  If a new
  	search engine were to be used, this is where it would be hooked in */
!      char *dbName = (aSearch->DatabaseNames == NULL) ?
!                            INFO_DATABASE_NAME : aSearch->DatabaseNames[0];
!      if (!strncmp(dbName, "DYNAMIC", strlen("DYNAMIC"))) {
!        search_status = run_dynamic_search(aSearch, headers, &diags, 
! 			index_directory, &seed_words_used, 
! 			waisProtocolVersion, &headerNum);
!      } else {
!        search_status = run_search(aSearch, headers, &diags, 
! 			index_directory, &seed_words_used, 
! 			waisProtocolVersion, &headerNum);
!      }
     }
  
  #define CATALOG_FOR_NO_RESULTS
***************
*** 919,924 ****
--- 930,936 ----
    long i;
    database* db;
    char* new_db_name;
+ 
    
    /* read the query */
    docs = readWAISTextQuery((any*)aSearch->Query);
***************
*** 971,977 ****
         }
         else element = NULL;
         closeDatabase(db);
!      }
       else if (doc->ChunkCode == CT_line)
         element = (void*)getDocumentText(doc, &errorCode, index_directory);
       else if (doc->ChunkCode == CT_byte)
--- 983,991 ----
         }
         else element = NULL;
         closeDatabase(db);
!      } else if (doc->Type != NULL && !strncmp(doc->Type, "DYNAMIC", 7)) {
!        element = (void*)getDynamicDocumentText(doc, &errorCode,index_directory);
!      } 
       else if (doc->ChunkCode == CT_line)
         element = (void*)getDocumentText(doc, &errorCode, index_directory);
       else if (doc->ChunkCode == CT_byte)
*** /tmp/hardy/wais-8-b5.1/ir/irretrvl.c	Sun May 10 15:43:57 1992
--- ir/irretrvl.c	Mon Jan 25 10:51:11 1993
***************
*** 10,15 ****
--- 10,18 ----
  
  /* Change log:
   * $Log:	irretrvl.c,v $
+  * Revision 1.31  93/01/18  14:37:53  hardy
+  * Dynamic WAIS support.
+  *
   * Revision 1.30  92/05/10  14:43:59  jonathan
   * 
   * Made a little safer on NULL docid's when parsing.
***************
*** 556,558 ****
--- 559,686 ----
    s_free(local_id);
    return(text);
  }
+ 
+ /* 
+  *  Retrieval support for Dynamic WAIS.  Based on irretrvl.c.
+  */
+ #define NETFIND_CMD 	"/homes/hardy/rd/DynamicWAIS/bin/netfind"
+ #define ARCHIE_CMD 	"/homes/hardy/rd/DynamicWAIS/bin/archie"
+ 
+ /*----------------------------------------------------------------------*/
+ WAISDocumentText* getNetfindDocumentText(doc, errorCode, index_directory)
+ DocObj* doc;
+ long* errorCode;
+ char* index_directory;
+ {
+ 	WAISDocumentText *text = NULL;
+ 	any 		*bufAny = NULL;
+ 	char		buf[65536], broken_domain[256], cmdbuf[8192];
+ 	char		*p, *q, c, *name, *domain, tfname[8192];
+ 	long		bytesRead = 0L;
+ 	FILE		*fp;
+ 	DocID		*theDocID;
+ 
+ 	sprintf(tfname, "/tmp/getNetfindText.%d", getpid());
+ 	strcpy(buf, doc->Type);
+ 	(void) strtok(buf, " ");		/* DYNAMIC */
+ 	(void) strtok(NULL, " ");		/* netfind */
+ 	name = strtok(NULL, " ");		/* name */
+ 	domain = strtok(NULL, " ");		/* domain */
+ 	for (p = broken_domain, q = domain; *q != '\0'; p++, q++)
+ 		*p = *q == '.' ? ' ' : *q;
+ 	*p = '\0';
+ 	sprintf(cmdbuf, "%s -L \"%s\" %s %s < /dev/null > %s 2>&1", 
+ 		NETFIND_CMD, domain, name, broken_domain, tfname);
+ 
+ 	waislog(WLOG_LOW, WLOG_INFO, "Running %s", cmdbuf);
+ 	(void) unlink(tfname);
+ 	(void) system(cmdbuf);
+ 	if ((fp = fopen(tfname, "r")) == NULL) {
+ 		waislog(WLOG_HIGH, WLOG_WARNING, "Cannot read %s", tfname);
+ 		return(NULL);
+ 	}
+ 	for (p = buf; ((c = (char) fgetc(fp)) != EOF); bytesRead++, p++)
+ 		*p = c;
+ 	*p = '\0';
+ 	fclose(fp);
+ 	(void) unlink(tfname);
+ 	*errorCode = GDT_NoError;
+ 	theDocID = docIDFromAny(doc->DocumentID);
+ 	bufAny = makeAny(bytesRead, buf);
+ 	text = makeWAISDocumentText(duplicateAny(doc->DocumentID),0L,bufAny);
+ 	return(text);
+ }
+ 
+ WAISDocumentText* getArchieDocumentText(doc, errorCode, index_directory)
+ DocObj* doc;
+ long* errorCode;
+ char* index_directory;
+ {
+ 	WAISDocumentText *text = NULL;
+ 	any 		*bufAny = NULL;
+ 	char		buf[65536], cmdbuf[8192], tfname[8192];
+ 	FILE		*fp;
+ 	char		*p, *q, c;
+ 	long		bytesRead = 0L;
+ 	DocID		*theDocID;
+ 
+ 	sprintf(tfname, "/tmp/getArchieText.%d", getpid());
+ 	sprintf(cmdbuf, "%s -h %s < /dev/null > %s 2>&1", 
+ 		ARCHIE_CMD, doc->Type + strlen("DYNAMIC archie"), tfname);
+ 
+ 	waislog(WLOG_LOW, WLOG_INFO, "Running %s", cmdbuf);
+ 	(void) unlink(tfname);
+ 	if (system(cmdbuf) != 0) {
+ 		waislog(WLOG_HIGH, WLOG_WARNING, 
+ 			"Problem with running %s", cmdbuf);
+ 	}
+ 	if ((fp = fopen(tfname, "r")) == NULL) {
+ 		waislog(WLOG_HIGH, WLOG_WARNING, "Cannot read %s", tfname);
+ 		return(NULL);
+ 	}
+ 	p = buf;
+ 	while ((c = (char) fgetc(fp)) != EOF) {
+ 		*p++ = c;
+ 		bytesRead++;
+ 	}
+ 	*p = '\0';
+ 	fclose(fp);
+ 	(void) unlink(tfname);
+ 	*errorCode = GDT_NoError;
+ 	theDocID = docIDFromAny(doc->DocumentID);
+ 	bufAny = makeAny(bytesRead, buf);
+ 	text = makeWAISDocumentText(duplicateAny(doc->DocumentID),0L,bufAny);
+ 	return(text);
+ }
+ 
+ WAISDocumentText* getDynamicDocumentText(doc, errorCode, index_directory)
+ DocObj* doc;
+ long* errorCode;
+ char* index_directory;
+ {
+ 	char *p, fileName[BUFSIZ];
+ 	long start, end;
+ 
+         if (doc->ChunkStart.Pos != 0) { 	/* return empty text */
+ 		WAISDocumentText *text = NULL;
+ 		any 		*bufAny = NULL;
+ 		char		buf[BUFSIZ];
+ 
+ 		buf[0] = '\0';
+ 		bufAny = makeAny(0, buf);
+ 		text = makeWAISDocumentText(duplicateAny(doc->DocumentID),0L,bufAny);
+ 		return(text);
+ 	}
+ 	p = doc->Type + strlen("DYNAMIC ");
+ 	waislog(WLOG_LOW, WLOG_INFO, "Dynamic Type: '%s' for %d, %d [%d, %d]", 
+ 	        p, start, end, doc->ChunkStart.Pos, doc->ChunkEnd.Pos);
+ 	if (!strncmp(p, "netfind", strlen("netfind"))) {
+ 		return (getNetfindDocumentText(doc, errorCode,index_directory));
+ 	} 
+ 	else if (!strncmp(p, "archie", strlen("archie"))) {
+ 		return (getArchieDocumentText(doc, errorCode,index_directory));
+ 	} 
+ 	waislog(WLOG_HIGH, WLOG_WARNING, "Unknown Dynamic Type: %s", p);
+ 	return (NULL);
+ }
+ 
*** /tmp/hardy/wais-8-b5.1/ir/irsearch.c	Sun May 10 15:44:33 1992
--- ir/irsearch.c	Sun Mar  7 12:37:44 1993
***************
*** 16,21 ****
--- 16,24 ----
   
  /* Change Log:
   * $Log:	irsearch.c,v $
+  * Revision 1.55  93/01/18  14:36:26  hardy
+  * Dynamic WAIS support
+  *
   * Revision 1.54  92/05/10  14:44:35  jonathan
   * Made a little safer on NULL docid's when parsing.
   * 
***************
*** 838,841 ****
--- 841,1166 ----
  #endif
  
    return(true);
+ }
+ 
+ /*
+  *  Search support for Dynamic WAIS.  Based on irsearch.c.
+  */
+ #define DBLOOKUP_CMD	"/homes/hardy/ds/proj/netfind/bin/dblookup"
+ 
+ FILE 	*domainfp = NULL;
+ char	netfind_args[8192];
+ char	archie_args[8192];
+ int	current_archie_server = 0;
+ char	*archie_servers[10] = {	/* static Archie servers */
+     "archie.rutgers.edu   128.6.18.15     (Rutgers University)",
+     "archie.unl.edu       129.93.1.14     (University of Nebraska in Lincoln)",
+     "archie.sura.net      128.167.254.179 (SURAnet archie server)",
+     "archie.ans.net       147.225.1.2     (ANS archie server)",
+     "archie.au            139.130.4.6     (Australian server)",
+     "archie.funet.fi      128.214.6.100   (European server in Finland)",
+     "archie.doc.ic.ac.uk  146.169.11.3    (UK/England server)",
+     "archie.cs.huji.ac.il 132.65.6.15     (Israel server)",
+     "archie.wide.ad.jp    133.4.3.6       (Japanese server)",
+     NULL
+ };
+ 
+ boolean netfind_next_best_hit();
+ boolean netfind_search_for_words();
+ WAISDocumentHeader *netfind_best_hit_to_header();
+ void netfind_finished_best_hit();
+ 
+ boolean archie_next_best_hit();
+ boolean archie_search_for_words();
+ WAISDocumentHeader *archie_best_hit_to_header();
+ void archie_finished_best_hit();
+ 
+ /*----------------------------------------------------------------------*/
+ 
+ boolean netfind_search_for_words(seedwords)
+ char *seedwords;
+ {
+ 	char 	*p, cmdbuf[8192];
+ 
+ 	strcpy(netfind_args, strtok(seedwords, " \t\n"));
+ 	strcpy(cmdbuf, DBLOOKUP_CMD);
+ 	while ((p = strtok(NULL, " \t\n")) != NULL) {
+ 		strcat(cmdbuf, " ");
+ 		strcat(cmdbuf, p);
+ 	}
+ 	if (domainfp != NULL) {	/* this shouldn't happen */
+ 		pclose(domainfp);
+ 	}
+ 	waislog(WLOG_LOW, WLOG_INFO, "Running %s", cmdbuf);
+ 	if ((domainfp = popen(cmdbuf, "r")) == NULL) {
+ 		return(false);
+ 	}
+ 	return (true);
+ }
+ 
+ boolean netfind_next_best_hit(hitbuf) 
+ hit 	*hitbuf;
+ {
+ 	char	buf[1024],
+ 		*index();
+ 	
+ 	/*
+ 	 *  Grab the next line of output from the netfind command 
+ 	 */
+ 	if (fgets(buf, 1024, domainfp) == NULL)
+ 		return (false);
+ 	*index(buf, '\n') = '\0';
+ 
+ 	/*
+ 	 *  Convert the netfind output to a "hit"
+ 	 */
+ 	hitbuf->weight = MAX_NORMAL_SCORE;
+ 	hitbuf->document_id = 0;
+ 	hitbuf->start_character = 0;
+ 	hitbuf->end_character = (1024 * 1024) - 1;
+ 	strcpy(hitbuf->filename, "Netfind Domain Result");
+ 	strcpy(hitbuf->headline, buf);
+ 	sprintf(hitbuf->type, "DYNAMIC netfind %s %s", 
+ 		netfind_args, strtok(buf, " "));
+ 	strcpy(hitbuf->date, "930101");
+ 	hitbuf->number_of_lines = 1024;
+ 	hitbuf->document_length = 1024 * 64;
+ 	hitbuf->best_character = 0;
+ 	hitbuf->best_line = 0;
+ 	hitbuf->db = NULL; 
+ }
+ 
+ void netfind_finished_best_hit()
+ {
+ 	pclose(domainfp);
+ }
+ 
+ WAISDocumentHeader *netfind_best_hit_to_header(best_hit, server)
+ hit 	*best_hit;
+ char 	*server;
+ {
+ 	WAISDocumentHeader* header;
+ 	DocID* 	theDocID = NULL;
+ 	char 	*originName = "Netfind.src",
+ 		**type = NULL,
+ 		local_id[MAX_FILENAME_LEN + 60]; /* filename, start, end */
+ 
+ 	local_id[0] = '\0';
+ 
+ 	sprintf(local_id, "%ld %ld %s", best_hit->start_character,
+       		best_hit->end_character, best_hit->filename);
+  
+ 	type = (char**)s_malloc((size_t)(sizeof(char*) * 2));
+ 	type[0] = s_strdup(best_hit->type);
+ 	type[1] = NULL;
+ 
+ 	theDocID = makeDocID();
+ 	theDocID->distributorServer = stringToAny(server);
+ 	theDocID->originalServer = stringToAny(server);
+ 	theDocID->distributorDatabase = stringToAny(originName);
+ 	theDocID->originalDatabase = stringToAny(originName);
+ 	theDocID->distributorLocalID = stringToAny(local_id);
+ 	theDocID->originalLocalID = stringToAny(local_id);
+ 	
+ 	header = makeWAISDocumentHeader(anyFromDocID(theDocID),
+ 		       			UNUSED,
+  					best_hit->weight,
+ 		       			best_hit->best_line,
+ 					best_hit->document_length,
+ 					best_hit->number_of_lines,
+ 		       			type,
+ 		       			s_strdup(originName),
+ 		       			s_strdup(best_hit->date),
+ 		       			s_strdup(best_hit->headline),
+ 		       			NULL);
+ 	freeDocID(theDocID);
+ 	return(header);
+ }
+ 
+ /*----------------------------------------------------------------------*/
+ 
+ boolean archie_search_for_words(seedwords)
+ char *seedwords;
+ {
+ 	strcpy(archie_args, seedwords);
+ 	current_archie_server = 0;
+ 	return (true);
+ }
+ 
+ boolean archie_next_best_hit(hitbuf) 
+ hit 	*hitbuf;
+ {
+ 	char buf[1024];
+ 
+ 	if (archie_servers[current_archie_server] == NULL) {
+ 		return (false);
+ 	}
+ 	strcpy(buf, archie_servers[current_archie_server++]);
+ 	/*
+ 	 *  Convert the archie output to a "hit"
+ 	 */
+ 	hitbuf->weight = MAX_NORMAL_SCORE;
+ 	hitbuf->document_id = 0;
+ 	hitbuf->start_character = 0;
+ 	hitbuf->end_character = (1024 * 1024) - 1;
+ 	strcpy(hitbuf->filename, "Archie Servers Result");
+ 	strcpy(hitbuf->headline, buf);
+ 	sprintf(hitbuf->type, "DYNAMIC archie %s %s", strtok(buf, " \t"), 
+ 		archie_args);
+ 	strcpy(hitbuf->date, "930301");
+ 	hitbuf->number_of_lines = 1024;
+ 	hitbuf->document_length = 64 * 1024;
+ 	hitbuf->best_character = 0;
+ 	hitbuf->best_line = 0;
+ 	hitbuf->db = NULL; 
+ 	return(true);
+ }
+ 
+ void archie_finished_best_hit()
+ {
+ 	/* do nothing */
+ }
+ 
+ WAISDocumentHeader *archie_best_hit_to_header(best_hit, server)
+ hit 	*best_hit;
+ char 	*server;
+ {
+ 	WAISDocumentHeader* header;
+ 	DocID* 	theDocID = NULL;
+ 	char 	*originName = "Archie.src",
+ 		**type = NULL,
+ 		local_id[MAX_FILENAME_LEN + 60]; /* filename, start, end */
+ 
+ 	local_id[0] = '\0';
+ 
+ 	sprintf(local_id, "%ld %ld %s", best_hit->start_character,
+       		best_hit->end_character, best_hit->filename);
+  
+ 	type = (char**)s_malloc((size_t)(sizeof(char*) * 2));
+ 	type[0] = s_strdup(best_hit->type);
+ 	type[1] = NULL;
+ 
+ 	theDocID = makeDocID();
+ 	theDocID->distributorServer = stringToAny(server);
+ 	theDocID->originalServer = stringToAny(server);
+ 	theDocID->distributorDatabase = stringToAny(originName);
+ 	theDocID->originalDatabase = stringToAny(originName);
+ 	theDocID->distributorLocalID = stringToAny(local_id);
+ 	theDocID->originalLocalID = stringToAny(local_id);
+ 	
+ 	header = makeWAISDocumentHeader(anyFromDocID(theDocID),
+ 		       			UNUSED,
+  					best_hit->weight,
+ 		       			best_hit->best_line,
+ 					best_hit->document_length,
+ 					best_hit->number_of_lines,
+ 		       			type,
+ 		       			s_strdup(originName),
+ 		       			s_strdup(best_hit->date),
+ 		       			s_strdup(best_hit->headline),
+ 		       			NULL);
+ 	freeDocID(theDocID);
+ 	return(header);
+ }
+ 
+ boolean run_dynamic_search(aSearch, headers, diags, index_directory, 
+ 		   	   seed_words_used, waisProtocolVersion, headerNum)
+ SearchAPDU 		*aSearch;
+ WAISDocumentHeader 	**headers; 		/* list of results */
+ diagnosticRecord 	***diags;  		/* list of diagnostics */
+ char 			*index_directory;
+ char 			**seed_words_used;  	/* called with enough space */
+ long 			waisProtocolVersion;
+ long 			*headerNum;
+ { 
+ 	diagnosticRecord 	*diag = NULL;
+ 	WAISSearch 		*wais_search = (WAISSearch*)aSearch->Query;
+ 	WAISDocumentHeader 	*header;
+ 	database 		*db = NULL;
+ 	long 			i,
+   				num_diags = 0;
+   	query_parameter_type	parameters;
+   	boolean 		search_result;
+   	char 			server[255];
+ 	char *server_name = NULL;
+ 	long tcp_port = 0;
+ 	char *p;
+ 	boolean (*dynamic_search_for_words)();
+ 	boolean (*dynamic_next_best_hit)();
+ 	WAISDocumentHeader *(*dynamic_best_hit_to_header)();
+ 	void (*dynamic_finished_best_hit)();
+ 
+ 	if ((aSearch->DatabaseNames == NULL) || 
+  	    (aSearch->DatabaseNames[0] == NULL)) {
+ 		return(false);
+ 	}
+ 	p = aSearch->DatabaseNames[0] + strlen("DYNAMIC ");
+ 	if (!strncmp(p, "netfind", strlen("netfind"))) {
+ 		dynamic_search_for_words = netfind_search_for_words;
+ 		dynamic_next_best_hit = netfind_next_best_hit;
+ 		dynamic_best_hit_to_header = netfind_best_hit_to_header;
+ 		dynamic_finished_best_hit = netfind_finished_best_hit;
+ 	} else if (!strncmp(p, "archie", strlen("archie"))) {
+ 		dynamic_search_for_words = archie_search_for_words;
+ 		dynamic_next_best_hit = archie_next_best_hit;
+ 		dynamic_best_hit_to_header = archie_best_hit_to_header;
+ 		dynamic_finished_best_hit = archie_finished_best_hit;
+ 	} else {
+ 		waislog(WLOG_HIGH, WLOG_WARNING, "Bad Dynamic search: %s", p);
+ 		return(false);
+ 	}
+ 
+ #ifdef GET_QUERY_TIMING
+ 	ftime(&s_time);
+ #endif
+ 
+ 	if (server_name != NULL)
+ 		sprintf(server, "%s:%d", server_name, tcp_port);
+ 	else
+ 		sprintf(server, "localhost:0");
+ 
+ 	/* until seed_words_used is supported */
+ 	strcpy(*seed_words_used, wais_search->SeedWords);
+ 
+ 	search_result = false;
+ 
+ 	search_result |= dynamic_search_for_words(wais_search->SeedWords);
+ 
+ 	if (search_result == true) { /* the search went ok */
+ 		hit best_hit;
+ 		for (i = 0; i < wais_search->MaxDocumentsRetrieved; i++) { 
+ 			if (! dynamic_next_best_hit(&best_hit)) 
+   				break;		/* out of hits */
+ 			if (best_hit.weight > 0) {
+   				WAISDocumentHeader* header = 
+     					dynamic_best_hit_to_header(&best_hit, server);
+   				if( NULL != header) {
+     					headers[(*headerNum)++] = header;
+     					headers[*headerNum] = NULL;
+   				}
+ 			}
+ 		}
+ 	} else {			/* something went awry in the search */
+ 		num_diags++;
+ 		diag = makeDiag(true, D_PermanentSystemError, "Serious error in server");
+ 		*diags = (diagnosticRecord**) s_realloc(*diags, (size_t)(sizeof(diagnosticRecord*) * num_diags));
+ 		(*diags)[num_diags-2] = diag;
+ 		(*diags)[num_diags-1] = NULL;
+ 	}
+ 	dynamic_finished_best_hit();
+ 
+ #ifdef GET_QUERY_TIMING
+ 	ftime(&e_time);
+ 	t_time += (e_time.time + e_time.millitm/1000.0) - 
+     		  (s_time.time + s_time.millitm/1000.0);
+ 	n_query++;
+ 	if ( n_query == 200 ) {
+ 		waislog(WLOG_LOW, WLOG_INFO, 
+ 			"searching 200 queries takes %f seconds.", t_time);
+ 		waislog(WLOG_LOW, WLOG_INFO, "average %f/query.", t_time/200.0);
+ 		n_query = 0;
+ 		t_time = 0;
+ 	}
+ #endif
+ 	return(true);
  }
*** /tmp/hardy/wais-8-b5.1/x/qcommands.c	Fri Jul 17 15:11:21 1992
--- x/qcommands.c	Sun Mar  7 20:33:40 1993
***************
*** 910,915 ****
--- 910,916 ----
      }
      else if (sb->textstruct->type == NULL ||
  	     substrcmp(sb->textstruct->type, "TEXT") ||
+ 	     substrcmp(sb->textstruct->type, "DYNAMIC") ||
  	     !strcmp(sb->textstruct->type, "WCAT")) {
        Arg args[2];
    
