www.pudn.com > socks5.zip > procquery.c


/*                                                                           */ 
/*  * procquery.c : Routines for processing results from Archie              */ 
/*  *                                                                        */ 
/*  * Originally part of the Prospero Archie client by Cliff Neuman          */ 
/*    (bcn@isi.edu).                                                         */ 
/*  * Modified by Brendan Kehoe (brendan@cygnus.com).                        */ 
/*  * Re-modified by George Ferguson (ferguson@cs.rochester.edu).            */ 
/*  *                                                                        */ 
/*  * Copyright (c) 1991 by the University of Washington                     */ 
/*  *                                                                        */ 
/*  * For copying and distribution information, please see the file          */ 
/*  * .                                                         */ 
/*  *                                                                        */ 
 
 
#include "pmachine.h" 
#include "pfs.h" 
#include "perrno.h" 
#include "archie.h" 
 
/* Defined in dirsend.c.  */ 
extern int client_dirsrv_timeout, client_dirsrv_retry; 
 
/* In archie.c.  */ 
extern char *program_name; 
extern FILE *archie_out; 
 
/* 
 * Functions defined here 
 */ 
static void display_link (), alex_name (); 
void procquery (); 
 
/* 
 * Data defined here 
 */ 
extern int pwarn, perrno; 
extern int listflag, sortflag, alex; 
 
int pfs_debug; 
 
static struct tm *presenttime; 
static char lastpath[MAX_VPATH] = "\001"; 
static char lasthost[MAX_VPATH] = "\001"; 
 
/* Print the contents of the given virtual link.  */ 
static void 
display_link (l) 
     VLINK l; 
{ 
    PATTRIB 	ap; 
    char	linkpath[MAX_VPATH]; 
    int		dirflag = 0; 
    int		size = 0; 
    char	*modes = ""; 
    char	archie_date[20]; 
    char	*gt_date = ""; 
    int		gt_year = 0; 
    int		gt_mon = 0; 
    int		gt_day = 0; 
    int		gt_hour = 0; 
    int		gt_min = 0; 
    int		special = listflag || alex; 
 
    /* Initialize local buffers */ 
    *archie_date = '\0'; 
 
    /* Remember if we're looking at a directory */ 
    if (sindex(l->type,"DIRECTORY")) 
	dirflag = 1; 
    else 
	dirflag = 0; 
     
    /* Extract the linkpath from the filename */ 
    strcpy(linkpath,l->filename); 
    *(linkpath + (strlen(linkpath) - strlen(l->name) - 1)) = '\0'; 
     
    /* Is this a new host? */ 
    if (strcmp(l->host,lasthost) != 0) { 
	if (!special) 
	    fprintf (archie_out, "\nHost %s\n\n",l->host); 
	strcpy(lasthost,l->host); 
	*lastpath = '\001'; 
    } 
     
    /* Is this a new linkpath (location)? */ 
    if(strcmp(linkpath,lastpath) != 0) { 
	if (!special) 
	    fprintf (archie_out, 
		     "    Location: %s\n",(*linkpath ? linkpath : "/")); 
	strcpy(lastpath,linkpath); 
    } 
     
    /* Parse the attibutes of this link */ 
    for (ap = l->lattrib; ap; ap = ap->next) { 
	if (strcmp(ap->aname,"SIZE") == 0) { 
	    sscanf(ap->value.ascii,"%d",&size); 
	} else if(strcmp(ap->aname,"UNIX-MODES") == 0) { 
	    modes = ap->value.ascii; 
	} else if(strcmp(ap->aname,"LAST-MODIFIED") == 0) { 
	    gt_date = ap->value.ascii; 
	    sscanf(gt_date,"%4d%2d%2d%2d%2d",>_year, 
		   >_mon, >_day, >_hour, >_min); 
	    if ((12 * (presenttime->tm_year + 1900 - gt_year) +  
					presenttime->tm_mon - gt_mon) > 6)  
		sprintf(archie_date,"%s %2d %4d",month_sname(gt_mon), 
			gt_day, gt_year); 
	    else 
		sprintf(archie_date,"%s %2d %02d:%02d",month_sname(gt_mon), 
			 gt_day, gt_hour, gt_min); 
	} 
    } 
     
    /* Print this link's information */ 
    if (listflag) 
    fprintf (archie_out, 
	     "%s %6d %s %s%s\n",gt_date,size,l->host,l->filename, 
	     (dirflag ? "/" : "")); 
    else if (alex) 
      alex_name (l->host, l->filename, dirflag); 
    else 
	fprintf (archie_out, 
		 "      %9s %s %10d  %s  %s\n",(dirflag ? "DIRECTORY" : "FILE"), 
		 modes,size,archie_date,l->name); 
 
    /* Free the attibutes */ 
    atlfree(l->lattrib); 
    l->lattrib = NULL; 
} 
 
/*	-	-	-	-	-	-	-	-	*/ 
/* 
 * procquery : Process the given query and display the results. If 
 *	sortflag is non-zero, then the results are sorted by increasing 
 *	date, else by host/filename. If listflag is non-zero then each 
 *	entry is printed on a separate, complete line. Note that listflag 
 *	is ignored by xarchie. 
 */ 
void 
procquery(host,str,max_hits,offset,query) 
char *host,*str; 
int max_hits,offset; 
Query query; 
{ 
    VLINK l; 
    time_t now; 
 
    /* initialize data structures for this query */ 
    (void)time(&now); 
    presenttime = localtime(&now); 
 
    /* Do the query */ 
    if (sortflag == 1) 
	l = archie_query(host,str,max_hits,offset,query,AQ_INVDATECMP,0); 
    else 
	l = archie_query(host,str,max_hits,offset,query,NULL,0); 
 
    /* Error? */ 
    if (perrno != PSUCCESS) { 
	if (p_err_text[perrno]) { 
	    if (*p_err_string) 
		fprintf(stderr, "%s: failed: %s - %s\n", 
			program_name, p_err_text[perrno], p_err_string); 
	    else 
	        fprintf(stderr, "%s failed: %s\n", 
			program_name, p_err_text[perrno]); 
	} else 
	    fprintf(stderr, "%s failed: Undefined error %d (prospero)", 
		    program_name, perrno); 
    } 
 
    /* Warning? */ 
    if (pwarn != PNOWARN) { 
	if (*p_warn_string) 
	    fprintf(stderr, "%s: Warning! %s - %s\n", program_name, 
		p_warn_text[pwarn], p_warn_string); 
	else 
	    fprintf(stderr, "%s: Warning! %s\n", program_name, p_warn_text[pwarn]); 
    } 
 
 
    /* Display the results */ 
 
    if (l == (VLINK)NULL && pwarn == PNOWARN && perrno == PSUCCESS) { 
	if (! listflag) puts ("No matches."); 
	exit (1); 
    } 
 
    *lasthost = '\001'; 
    *lastpath = '\001'; 
    while (l != NULL) { 
	display_link (l); 
	l = l->next; 
    } 
} 
 
/* Given a dotted hostname, return its Alex root.  */ 
static char * 
alex_reverse (string, len) 
     char *string; 
     int len; 
{ 
  register char *p, *q; 
  register int i = 0; 
  char *buf = (char *) malloc (len); 
 
  p = buf; 
  q = (char *) (string + len - 1); 
  while (q > string) 
    { 
      for (i = 0; q > string; q--, i++) 
	if (*q == '.') 
	  { 
	    q++; 
	    break; 
	  } 
      if (q == string) 
	i++; 
      strncpy (p, q, i); 
      p += i; 
      *p++ = '/'; 
      i = 0; 
      q -= 2; 
    } 
  *--p = '\0'; 
  return buf; 
} 
 
/* Emit a string that's the Alex filename for the given host and file.  */ 
static void 
alex_name (host, file, dirp) 
     char *host, *file; 
     int dirp; 
{ 
  int hostlen = strlen (host); 
  int len = 6 + hostlen + strlen (file) + dirp +  1; 
  char *buf = (char *) malloc (len); 
 
  if (! buf) 
    exit (99); 
 
  sprintf (buf, "/alex/%s%s", alex_reverse (host, hostlen), file); 
  if (dirp) 
    { 
      len -= dirp; 
      buf[len - 1] = '/'; 
      buf[len] = '\0'; 
    } 
 
  fputs (buf, archie_out); 
}