⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aquery.c

📁 sock5代理服务器源代码
💻 C
字号:
/*                                                                           *//*  * aquery.c : Programmatic Prospero interface to Archie                   *//*  *                                                                        *//*  * Copyright (c) 1991 by the University of Washington                     *//*  *                                                                        *//*  * For copying and distribution information, please see the file          *//*  * <copyright.h>.                                                         */#include "pmachine.h"#include "pfs.h"#include "perrno.h"#include "archie.h"static void translateArchieResponse();inline static int hostnamecmp();extern int pwarn;extern char p_warn_string[];/*                                                                           *//*  * archie_query : Sends a request to _host_, telling it to search for     *//*  * _string_ using _query_ as the search method.                           *//*  * No more than _max_hits_ matches are to be returned                     *//*  * skipping over _offset_ matches.                                        *//*  *                                                                        *//*  * archie_query returns a linked list of virtual links.                   *//*  * If _flags_ does not include AQ_NOTRANS, then the Archie                *//*  * responses will be translated. If _flags_ does not include              *//*  * AQ_NOSORT, then the list will be sorted using _cmp_proc_ to            *//*  * compare pairs of links.  If _cmp_proc_ is NULL or AQ_DEFCMP,           *//*  * then the default comparison procedure, defcmplink(), is used           *//*  * sorting by host, then filename. If cmp_proc is AQ_INVDATECMP           *//*  * then invdatecmplink() is used, sorting inverted by date.               *//*  * otherwise a user-defined comparison procedure is called.               *//*  *                                                                        *//*  * archie_query returns NULL and sets perrno if the query                 *//*  * failed. Note that it can return NULL with perrno == PSUCCESS           *//*  * if the query didn't fail but there were simply no matches.             *//*  *                                                                        *//*  * query: S Substring search ignoring case                                *//*  * C Substring search with case significant                               *//*  * R Regular expression search                                            *//*  * = Exact String Match                                                   *//*  * s,c,e Tries exact match first and falls back to S, C, or R             *//*  * if not found.                                                          *//*  *                                                                        *//*  * cmp_proc: AQ_DEFCMP Sort by host, then filename                        *//*  * AQ_INVDATECMP Sort inverted by date                                    *//*  *                                                                        *//*  * flags: AQ_NOSORT Don't sort results                                    *//*  * AQ_NOTRANS Don't translate results                                     */VLINK archie_query(host,string,max_hits,offset,query,cmp_proc,flags)    char	*host,*string;    int		max_hits,offset;    Query	query;    int		(*cmp_proc)();    int		flags;    {	char qstring[MAX_VPATH];    /* For construting the query             */	VLINK	links;		/* Matches returned by server                */	VDIR_ST	dir_st;         /* Filled in by get_vdir                     */	PVDIR	dir= &dir_st;		VLINK	p,q,r,lowest,nextp,pnext,pprev;	int	tmp;	/* Set the cmp_proc if not given                                     */	if (cmp_proc == NULL) cmp_proc = defcmplink;	/* Make the query string                                             */	sprintf(qstring,"ARCHIE/MATCH(%d,%d,%c)/%s",		max_hits,offset, (char) query,string);	/* Initialize Prospero structures                                    */	perrno = PSUCCESS; *p_err_string = '\0';	pwarn = PNOWARN; *p_warn_string = '\0';	vdir_init(dir);		/* Retrieve the list of matches, return error if there was one       */	if((tmp = get_vdir(host,qstring,"",dir,GVD_ATTRIB|GVD_NOSORT,NULL,NULL))) {	    perrno = tmp;	    return(NULL);	}	/* Save the links, and clear in dir in case it's used again          */	links = dir->links; dir->links = NULL;	/* As returned, list is sorted by suffix, and conflicting suffixes   */	/* appear on a list of "replicas".  We want to create a              */	/* one-dimensional list sorted by host then filename and maybe by    */	/* some other parameter                                              */	/* First flatten the doubly-linked list                              */	for (p = links; p != NULL; p = nextp) {	    nextp = p->next;	    if (p->replicas != NULL) {		p->next = p->replicas;		p->next->previous = p;		for (r = p->replicas; r->next != NULL; r = r->next) /*EMPTY*/ ;		r->next = nextp;		nextp->previous = r;		p->replicas = NULL;	    }	}	/* Translate the filenames unless NOTRANS was given                  */	if (!(flags & AQ_NOTRANS))	    for (p = links; p != NULL; p = p->next)		translateArchieResponse(p);	/* If NOSORT given, then just hand it back                           */	if (flags & AQ_NOSORT) {	    perrno = PSUCCESS;	    return(links);	}	/* Otherwise sort it using a selection sort and the given cmp_proc   */	for (p = links; p != NULL; p = nextp) {	    nextp = p->next;	    lowest = p;	    for (q = p->next; q != NULL; q = q->next)		if ((*cmp_proc)(q,lowest) < 0)		    lowest = q;	    if (p != lowest) {		/* swap the two links                                        */		pnext = p->next;		pprev = p->previous;		if (lowest->next != NULL)		    lowest->next->previous = p;		p->next = lowest->next;		if (nextp == lowest) {		    p->previous = lowest;		} else {		    lowest->previous->next = p;		    p->previous = lowest->previous;		}		if (nextp == lowest) {		    lowest->next = p;		} else {		    pnext->previous = lowest;		    lowest->next = pnext;		}		if (pprev != NULL)		    pprev->next = lowest;		lowest->previous = pprev;		/* keep the head of the list in the right place              */		if (links == p)		    links = lowest;	    }	}	/* Return the links                                                  */	perrno = PSUCCESS;	return(links);    }/*                                                                           *//*  * translateArchieResponse:                                               *//*  *                                                                        *//*  * If the given link is for an archie-pseudo directory, fix it.           *//*  * This is called unless AQ_NOTRANS was given to archie_query().          */static voidtranslateArchieResponse(l)    VLINK l;    {	char *slash;	if (strcmp(l->type,"DIRECTORY") == 0) {	    if (strncmp(l->filename,"ARCHIE/HOST",11) == 0) {		l->type = stcopyr("EXTERNAL(AFTP,DIRECTORY)",l->type);		l->host = stcopyr(l->filename+12,l->host);		slash = (char *)index(l->host,'/');		if (slash) {		    l->filename = stcopyr(slash,l->filename);		    *slash++ = '\0';		} else		    l->filename = stcopyr("",l->filename);	    }	}    }/* hostnamecmp: Compare two hostnames based on domain,                       *//*  * right-to-left.  Returns <0 if a belongs before b, >0                   *//*  * if b belongs before a, and 0 if they are identical.                    *//*  * Contributed by asami@cs.berkeley.edu (Satoshi ASAMI).                  */inline static inthostnamecmp(a,b)    char *a,*b;    {	char	*pa, *pb;	int	result;	for (pa = a ; *pa ; pa++)	    ;	for (pb = b ; *pb ; pb++)	    ;	while (pa > a && pb > b) {	    for (; pa > a ; pa--)		if (*pa == '.')	{		    pa++;		    break;		}	    for (; pb > b ; pb--)		if (*pb == '.')	{		    pb++;		    break;		}	    if ((result = strcmp(pa, pb)))		return (result);	    pa -= 2;	    pb -= 2;	}	if (pa <= a) {	    if (pb <= b)		return (0);	    else		return (-1);	} else	    return (1);    }/*                                                                           *//*  * defcmplink: The default link comparison function for sorting. Compares *//*  * links p and q first by host then by filename. Returns < 0 if p         *//*  * belongs before q, > 0 if p belongs after q, and == 0 if their          *//*  * host and filename fields are identical.                                */intdefcmplink(p,q)    VLINK p,q;    {	int result;	if ((result=hostnamecmp(p->host,q->host)) != 0)	    return(result);	else	    return(strcmp(p->filename,q->filename));    }/*                                                                           *//*  * invdatecmplink: An alternative comparison function for sorting that    *//*  * compares links p and q first by LAST-MODIFIED date,                    *//*  * if they both have that attribute. If both links                        *//*  * don't have that attribute or the dates are the                         *//*  * same, it then calls defcmplink() and returns its                       *//*  * value.                                                                 */intinvdatecmplink(p,q)    VLINK p,q;    {	PATTRIB pat,qat;	char *pdate,*qdate;	int result;		pdate = qdate = NULL;	for (pat = p->lattrib; pat; pat = pat->next)	    if(strcmp(pat->aname,"LAST-MODIFIED") == 0)		pdate = pat->value.ascii;	for (qat = q->lattrib; qat; qat = qat->next)	    if(strcmp(qat->aname,"LAST-MODIFIED") == 0)		qdate = qat->value.ascii;	if(!pdate && !qdate) return(defcmplink(p,q));	if(!pdate) return(1); 	if(!qdate) return(-1);	if((result=strcmp(qdate,pdate)) == 0) return(defcmplink(p,q));	else return(result);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -