/* */ /* * 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); }