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

📄 get_vdir.c

📁 socket5 代理服务代码 socket5 代理服务代码
💻 C
字号:
/* * Copyright (c) 1989, 1990, 1991 by the University of Washington * * For copying and distribution information, please see the file * <copyright.h>. */#include "pmachine.h"#include "pfs.h"#include "pprot.h"#include "perrno.h"#include "pcompat.h"#include "pauthent.h"#ifdef DEBUGextern int	pfs_debug;#endifextern int	pwarn;extern char	p_warn_string[];extern int	perrno;extern char	p_err_string[];/* * get_vdir - Get contents of a directory given its location * *	      GET_VDIR takes a directory location, a list of desired *	      components, a pointer to a directory structure to be  *	      filled in, and flags.  It then queries the appropriate  *	      directory server and retrieves the desired information. * *      ARGS:   dhost       - Host on which directory resides *              dfile       - Directory on that host *              components  - The names from the directory we want *		dir	    - Structure to be filled in *	        flags       - Options.  See FLAGS *		filters     - filters to be applied to result  *              acomp       - Pointer to remaining components * *     FLAGS:	GVD_UNION   - Do not expand union links *		GVD_EXPAND  - Expand union links locally *		GVD_REMEXP  - Request remote expansion (& local if refused) *		GVD_LREMEXP - Request remote expansion of local union links *		GVD_VERIFY  - Only verify that args are for a directory *              GVD_ATTRIB  - Request attributes from directory server *              GVD_NOSORT  - Do not sort links when adding to directory * *   RETURNS:   PSUCCESS (0) or error code *		On some codes addition information in p_err_string * *     NOTES:   If acomp is non-null the string it points to might be modified * *              If the directory passed as an argument already has *		links or union links, then those lists will be freed *              before the new contents are filled in. * *              If a filter is passed to the procedure, and application of *              the filter results in additional union link, then those links *              will (or will not) be expanded as specified in the FLAGS field. * *              If the list of components in NULL, or the null string, then *              get_vdir will return all links in the requested directory. * *      BUGS:   Doesn't process union links yet *              Doesn't process errors returned from server *		Doesn't expand union links if requested to */intget_vdir(dhost,dfile,components,dir,flags,filters,acomp)    char	*dhost;		/* Host on which directory resides           */    char	*dfile;		/* Name of file on that host	             */    char	*components;	/* Component name (wildcards allowed)        */    PVDIR	dir;		/* Structure to be filled in		     */    long	flags;		/* Flags			             */    VLINK	filters;	/* Filters to be applied to result           */    char	*acomp;		/* Components left to be resolved            */    {        PTEXT	request;	/* Text of request to dir server             */	PTEXT	resp;	    	/* Response from dir server	             */	char	ulcomp[MAX_VPATH];/* Work space for new current component    */	char	*comp = components;	VLINK	cur_link = NULL;/* Current link being filled in              */	VLINK 	exp = NULL; 	/* The current ulink being expanded	     */	VLINK	pul = NULL;     /* Prev union link (insert new one after it) */	VLINK	l;		/* Temp link pointer 			     */	int	mcomp;		/* Flag - check multiple components          */	int	unresp;		/* Flag - received unresolved response       */	int	getattrib = 0;  /* Get attributes from server                */	int	vl_insert_flag; /* Flags to vl_insert                        */	int	fwdcnt = MAX_FWD_DEPTH;	int	no_links = 0;   /* Count of number of links found	     */	char	options[40];    /* LIST option                               */	char	*opt;           /* After leading +                           */	PAUTH	authinfo;	/* Treat null string like NULL (return entire directory) */	if(!components || !*components) comp = NULL;	if(acomp && !filters) mcomp = 1;	else mcomp = 0;	if(flags&GVD_ATTRIB) {	    getattrib++;	    flags &= (~GVD_ATTRIB);	}	if(flags&GVD_NOSORT) vl_insert_flag = VLI_NOSORT;	else vl_insert_flag = VLI_ALLOW_CONF;	flags &= (~GVD_NOSORT);	if(filters) comp = NULL;	perrno = 0;	authinfo = get_pauth(PFSA_UNAUTHENTICATED);	*options = '\0';	if(getattrib) {	    strcat(options,"+ATTRIBUTES");	    flags &= (~GVD_ATTRIB);	}	if(!filters) { /* Can't do remote expansion if filters to be applied */	    if(flags == GVD_REMEXP) strcat(options,"+EXPAND");	    if(flags == GVD_LREMEXP) strcat(options,"+LEXPAND");	}	/* If all we are doing is verifying that dfile is a directory */	/* then we do not want a big response from the directory      */	/* server.  A NOT-FOUND is sufficient.			      */	if(flags == GVD_VERIFY)#ifdef NEWVERIFYOPT	    strcat(options,"+VERIFY");#else	comp = "%#$PRobably_nOn_existaNT$#%";#endif	if(*options) opt = options+1;	else opt = "''";    startover:	request = ptalloc();	sprintf(request->start,		"VERSION %d %s\nAUTHENTICATOR %s %s\nDIRECTORY ASCII %s\nLIST %s COMPONENTS %s%s%s\n",		VFPROT_VNO, PFS_SW_ID, authinfo->auth_type,		authinfo->authenticator, dfile, opt,		(comp ? comp : ""), (mcomp ? "/" : ""),		(mcomp ? acomp : ""));	request->length = strlen(request->start);#ifdef DEBUG	if(pfs_debug > 2)	    fprintf(stderr,"Sending message to dirsrv:\n%s",request->start);#endif	resp = dirsend(request,dhost,0);#ifdef DEBUG	if(pfs_debug && (resp == NULL)) {	    fprintf(stderr,"Dirsend failed: %d\n",perrno);	}#endif	/* If we don't get a response, then if the requested       */	/* directory, return error, if a ulink, mark it unexpanded */	if(resp == NULL) {	    if(exp) exp->expanded = FAILED;	    else return(perrno);	}	unresp = 0;	/* Here we must parse reponse and put in directory */	/* While looking at each packet 		   */	while(resp) {	    PTEXT		vtmp;	    char		*line;	    vtmp = resp;#ifdef DEBUG	    if(pfs_debug > 3) fprintf(stderr,"%s\n",resp->start);#endif	    /* Look at each line in packet */	    for(line = resp->start;line != NULL;line = nxtline(line)) {		switch (*line) {		    		    /* Temporary variables to hold link info */		    char	l_linktype;		    char 	l_name[MAX_DIR_LINESIZE];		    char	l_type[MAX_DIR_LINESIZE];		    char 	l_htype[MAX_DIR_LINESIZE];		    char 	l_host[MAX_DIR_LINESIZE];		    char 	l_ntype[MAX_DIR_LINESIZE];		    char 	l_fname[MAX_DIR_LINESIZE];		    int		l_version;		    char 	t_unresolved[MAX_DIR_LINESIZE];		    int		l_magic;		    int		tmp;		case 'L': /* LINK or LINK-INFO */		    if(strncmp(line,"LINK-INFO",9) == 0) {			PATTRIB		at;			PATTRIB		last_at;			at = parse_attribute(line);			if(!at) break;			/* Cant have link info without a link */			if(!cur_link) {			    perrno = DIRSRV_BAD_FORMAT;			    atfree(at);			    break;			}						if(cur_link->lattrib) {			    last_at = cur_link->lattrib;			    while(last_at->next) last_at = last_at->next;			    at->previous = last_at;			    last_at->next = at;			}			else {			    cur_link->lattrib = at;			    at->previous = NULL;			}			break;		    }		    /* Not LINK-INFO, must be LINK - if not check for error */		    if(strncmp(line,"LINK",4) != 0) goto scanerr;		    /* If only verifying, don't want to change dir */		    if(flags == GVD_VERIFY) {			break;		    }		    /* If first link and some links in dir, free them */		    if(!no_links++) {			if(dir->links) vllfree(dir->links); dir->links=NULL;			if(dir->ulinks) vllfree(dir->ulinks); dir->ulinks=NULL;			}					    cur_link = vlalloc();		    /* parse and insert file info */		    tmp = sscanf(line,"LINK %c %s %s %s %s %s %s %ld %ld", &l_linktype,				 l_type,l_name,l_htype,l_host,l_ntype,l_fname,				 &(cur_link->version),				 &(cur_link->f_magic_no));		    if(tmp != 9) {			perrno = DIRSRV_BAD_FORMAT;			vlfree(cur_link);			break;		    }		    cur_link->linktype = l_linktype;		    cur_link->type = stcopyr(l_type,cur_link->type);		    cur_link->name = stcopyr(unquote(l_name),cur_link->name);		    cur_link->hosttype = stcopyr(l_htype,cur_link->hosttype);		    cur_link->host = stcopyr(l_host,cur_link->host);		    cur_link->nametype = stcopyr(l_ntype,cur_link->nametype);		    cur_link->filename = stcopyr(l_fname,cur_link->filename);		    /* Double check to make sure we don't get */		    /* back unwanted components		      */		    /* OK to keep if special (URP) links      */		    /* or if mcomp specified                  */		    if(!mcomp && (cur_link->linktype == 'L') && 		       (!wcmatch(cur_link->name,comp))) {			vlfree(cur_link);			break;		    }		    /* If other optional info was sent back, it must */		    /* also be parsed before inserting link     ***  */		    		    		    if(cur_link->linktype == 'L') 			vl_insert(cur_link,dir,vl_insert_flag);		    else {			tmp = ul_insert(cur_link,dir,pul);			/* If inserted after pul, next one after cur_link */			if(pul && (!tmp || (tmp == UL_INSERT_SUPERSEDING)))			    pul = cur_link;		    }		    		    break;		case 'F': /* FILTER, FAILURE or FORWARDED */		    /* FORWARDED */		    if(strncmp(line,"FORWARDED",9) == 0) {			if(fwdcnt-- <= 0) {			    ptlfree(resp);			    perrno = PFS_MAX_FWD_DEPTH;			    return(perrno);			}			/* parse and start over */			tmp = sscanf(line,"FORWARDED %s %s %s %s %d %d", 				     l_htype,l_host,l_ntype,l_fname,				     &l_version, &l_magic);			dhost = stcopy(l_host);			dfile = stcopy(l_fname);			if(tmp < 4) {			    perrno = DIRSRV_BAD_FORMAT;			    break;			}			ptlfree(resp);			goto startover;		    }		    if(strncmp(line,"FILTER",6) != 0) goto scanerr;		    break;		case 'M': /* MULTI-PACKET (processed by dirsend) */		case 'P': /* PACKET (processed by dirsend) */		    break;		case 'N': /* NOT-A-DIRECTORY or NONE-FOUND */		    /* NONE-FOUND, we just have no links to insert */		    /* It is not an error, but we must clear any   */		    /* old links in the directory arg              */		    if(strncmp(line,"NONE-FOUND",10) == 0) {			/* If only verifying, don't want to change dir */			if(flags == GVD_VERIFY) {			    break;			}			/* If first link and some links in dir, free them */			if(!no_links++) {			    if(dir->links) vllfree(dir->links);			    if(dir->ulinks) vllfree(dir->ulinks);			    dir->links = NULL;			    dir->ulinks = NULL;			}			break;		    }		    /* If NOT-A-DIRECTORY or anything else, scan error */		    goto scanerr;		case 'U': /* UNRESOLVED */		    if(strncmp(line,"UNRESOLVED",10) != 0) {			goto scanerr;		    }		    tmp = sscanf(line,"UNRESOLVED %s", t_unresolved);		    if(tmp < 1) {			perrno = DIRSRV_BAD_FORMAT;			break;		    }		    /* If multiple components were resolved */		    if(strlen(t_unresolved) < strlen(acomp)) {			strcpy(ulcomp,acomp);			/* ulcomp is the components that were resolved */			*(ulcomp+strlen(acomp)-strlen(t_unresolved)-1) = '\0';			/* Comp gets the last component resolved */			comp = (char *) rindex(ulcomp,'/');			if(comp) comp++;			else comp = ulcomp;			/* Let rd_vdir know what remains */			strcpy(acomp,t_unresolved);		    }		    unresp = 1;		    break;		case 'V': /* VERSION-NOT-SUPPORTED */		    if(strncmp(line,"VERSION-NOT-SUPPORTED",21) == 0) {			perrno = DIRSRV_BAD_VERS;			return(perrno);		    }		    goto scanerr;		scanerr:		default:		    if(*line && (tmp = scan_error(line))) {			ptlfree(resp);			return(tmp);		    }		    break;		}	    }	    resp = resp->next;	    ptfree(vtmp);	}	/* We sent multiple components and weren't told any */	/* were unresolved                                  */	if(mcomp && !unresp) {	    /* ulcomp is the components that were resolved */	    strcpy(ulcomp,acomp);	    /* Comp gets the last component resolved */	    comp = (char *) rindex(ulcomp,'/');	    if(comp) comp++;	    else comp = ulcomp;	    /* If we have union links to resolve, only one component remains */	    mcomp = 0;	    /* Let rd_vdir know what remains */	    *acomp = '\0';	}	/* If only verifying, we already know it is a directory */	if(flags == GVD_VERIFY) return(PSUCCESS);	/* Don't return if matching was delayed by the need to filter    */	/* if FIND specified, and dir->links is non null, then we have   */	/* found a match, and should return.                             */	if((flags & GVD_FIND) && dir->links && (!filters))	    return(PSUCCESS);	/* If expand specified, and ulinks must be expanded, making sure */        /* that the order of the links is maintained properly            */	if((flags != GVD_UNION) && (flags != GVD_VERIFY)) {	    l = dir->ulinks;	    /* Find first unexpanded ulink */	    while(l && l->expanded && (l->linktype == 'U')) l = l->next;	    	    /* Only expand if a FILE or DIRECTORY -  Mark as  */            /* failed otherwise                               */	    /* We must still add support for symbolic ulinks */	    if(l) {		if ((strcmp(l->type,"DIRECTORY") == 0) || 		    (strcmp(l->type,"FILE") == 0)) {		    l->expanded = TRUE;		    exp = l;		    pul = l;		    dhost = l->host;		    dfile = l->filename;		    goto startover; /* was get_contents; */		}		else l->expanded = FAILED;	    }	}	/* Double check to make sure we don't get */	/* back unwanted components		  */	/* OK to keep if special (URP) links      */	if(components && *components) {	    l = dir->links;	    while(l) {		VLINK	ol;		if((l->linktype == 'L') && (!wcmatch(l->name,components))) {		    if(l == dir->links)			dir->links = l->next;		    else l->previous->next = l->next;		    if(l->next) l->next->previous = l->previous;		    ol = l;		    l = l->next;		    vlfree(ol);		}		else l = l->next;	    }	}	return(PSUCCESS);    }

⌨️ 快捷键说明

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