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

📄 reslink.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)reslink.c	4.1  (ULTRIX) 7/3/90";#endif/* *			Copyright (c) 1988 by *		Digital Equipment Corporation, Maynard, MA *			All rights reserved. *								 *	This software is furnished under a license and may be used and *	copied  only  in accordance with the terms of such license and *	with the  inclusion  of  the  above  copyright  notice.   This *	software  or  any  other copies thereof may not be provided or *	otherwise made available to any other person.  No title to and *	ownership of the software is hereby transferred.		 *								 *	The information in this software is subject to change  without *	notice  and should not be construed as a commitment by Digital *	Equipment Corporation.					 *								 *	Digital assumes no responsibility for the use  or  reliability *	of its software on equipment which is not supplied by Digital. */#include  <sys/types.h>#include  <sys/stat.h>#include  <sys/param.h>#include  <stdio.h>typedef struct visit {	struct visit	*v_next;	char		v_path[MAXPATHLEN];	int		v_cnt;} visit_t;/************************************************************************  Original - 06 November 87,	Teoman Topcubasi,*				Charley Bennett**  This subroutine will check for symbolic link references and replace*  them with the file name contained within the link!  It is written *  recursively, so that the resolved name is also checked again.*  *  This is called from utilities like editors in handling file names *  **********************************************************************/static visit_t *visits = NULL;/************************************************************************  getdir(f,j) will  extract the directory portion within a pathname*  *  input parameter: char *f	contains the pathname*  output parameters: int *j	contains the index to the last element *				of the path which identifies the*				directory*  return value:  char *	contains the part of the path specifying*				the directory.**********************************************************************/static  char  *getdir(f,j)   char	*f;   int  *j;	{	char tmp[MAXPATHLEN], *k;	k = (char *) rindex(f,'/');	if (k == 0)	   return(NULL);	strcpy (tmp,k);		/* now it contains the remainder after dir. */	*j = strlen (tmp);	*j = strlen(f) - *j;	strncpy (tmp, f, *j);	tmp[*j] = '\0';	return(tmp);	}/*************************************************************************  makevisit(v,path) will record a visit to each file name encountered*  in the link chain.**  input parameter: visit_t *v	a pointer to a linked list or NULL*  		    char *path	present pathname to be resolved*  return value:  visit_t *	a pointer to the newest element in the*				linked list.************************************************************************/static visit_t *makevisit(v,path)visit_t *v;char *path;{	visit_t	*t;	t = (visit_t *) malloc( sizeof(visit_t) );	strcpy( t->v_path, path );	if( v )		t->v_cnt = v->v_cnt + 1;	else		t->v_cnt = 1;	t->v_next = v;	return(t);}/************************************************************************  checkvisit(v,p) will recursively look if the path to be resolved *  has already been visited by reslink or not.**  input parameter: visit_t *v	contains a pointer to the linked list of*				visited file names.*		    char *path	contains the unresolved pathname*  return value:  visit_t *	either 0 if list is NULL or*				-1 if file name already encountered.***********************************************************************/static visit_t *checkvisit(v,path)visit_t *v;char *path;{	if( v == NULL )		return(0);	if( !strcmp( v->v_path, path ) )		return((visit_t *) -1);	return( checkvisit(v->v_next,path) );}/*************************************************************************  freevisit(v) will free the dynamic linked list of file names which *  have been visited by reslink.**  input/output parameters: visit_t *v	contains a pointer to a list*  return value:  visit_t *	always a NULL.************************************************************************/static visit_t *freevisits(v)visit_t *v;{	visit_t	*t;	if( v == NULL )		return(NULL);	t = v->v_next;	free(v);	return(freevisits(t));}/*************************************************************************  reslink(pathname) will resolve a file name which could be a soft link*  to its absolute value.  It is a recursive function and has been*  written with the intend of fixing old software which don't tolerate *  softly linked files.**	Example:	j --> /etc/fstab*			(here j is a link pointing to /etc/fstab)*			crontab --> ../../etc/crontab*			(here crontab is a link pointing to a file*			relative to its present location in the file *			system hierarchy)**  input parameter:  char *pathname	contains any file name*  return value:  char *		contains the resolved absolute*					pathname referred by the link.*************************************************************************/char  *reslink (pathname)char  *pathname;{	struct stat Lc;	static visit_t  *visit = NULL;	int rc;	int i, j=0;	char  *wd,	      buf[MAXPATHLEN],	      fname[MAXPATHLEN],	      *cwd, *dirname, *temp;	lstat(pathname, &Lc);	/* check if it is a link */	if ((Lc.st_mode & S_IFMT) != S_IFLNK)	{		if (visits->v_cnt > 1)		    chdir(cwd);		visits = (visit_t *)freevisits(visits);		return(pathname);	}	else			/* yes it is! */	{			/* read the link */	   if ((rc = readlink(pathname, buf, MAXPATHLEN)) < 0)		{		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *) freevisits(visits);			return(NULL);		}	   if (!strcmp(pathname,buf))	/* check if link points to */		{			/* itself */		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *) freevisits(visits);			return(NULL);		}	 /* save cwd */           if (!visits)		if ((cwd =  (char *)getcwd((char *)NULL, MAXPATHLEN)) == NULL)		{			visits = (visit_t *) freevisits(visits);			return(NULL);		} 	 /* check for directories in input path */			   if (dirname = getdir(pathname,&i))   /* save dir name */	   {	   	if ((rc = chdir(dirname)) < 0)	   	{		   if (visits->v_cnt > 1)		       chdir(cwd);			   visits = (visit_t *) freevisits(visits);			   return(NULL);	   	}	   	while (pathname[i++] != '\0')   /* save file name */	   	{			fname[j++] = pathname[i];	   	}	   	fname[j] = pathname[i];		strcpy (pathname, fname);	   }	   if (buf[0] == '/')	/* link name absolute */	   {		strcpy(pathname, buf);		if( checkvisit( visits, pathname ) )		{		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *) freevisits(visits);			return(NULL);		}		if (visit)		    if (visit->v_cnt > MAXSYMLINKS)		        return (NULL);		visits = (visit_t *) makevisit( visit, pathname );		reslink(pathname);	   }	   else 		/* link name relative */	   {		if (pathname[0] != '/')	/* file is relative */		{		   if ((wd = (char *) getcwd((char *)NULL, MAXPATHLEN)) == NULL)		   {		     if (visits->v_cnt > 1)		        chdir(cwd);		     visits = (visit_t *)freevisits(visits);		     return(NULL);		   }		   else		   {			strncat(wd, "/", 1);			strcat(wd, buf);			strcpy(pathname, wd);		   }		}		/* file name is full path */				dirname = getdir(pathname,&i);    /* save dir name */		if ((rc = chdir(dirname)) < 0)		{		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *) freevisits(visits);			return(NULL);		}		j = 0;		while (pathname[i++] != '\0')   /* save file name */		{			fname[j++] = pathname[i];		}		fname[j] = pathname[i];		if (0 == getwd(wd))		{		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *)freevisits(visits);			return(NULL);		}		else		{			strncat(wd, "/", 1);			strcat(wd, fname);			strcpy(pathname, wd);		}		if( checkvisit (visits,pathname) )		{		if (visits->v_cnt > 1)		    chdir(cwd);			visits = (visit_t *) freevisits(visits);			return(NULL);		}		if (visit)		    if (visit->v_cnt > MAXSYMLINKS)		    {			chdir(cwd);		        return (NULL);		    }		visits = (visit_t *) makevisit(visit, pathname);		reslink(pathname);	   }    }}

⌨️ 快捷键说明

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