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

📄 mksymlink.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1991 Peter J. Nicklin. * Copyright (c) 1991 Version Technology. * All Rights Reserved. * * $License: VT.1.1 $ * Redistribution and use in source and binary forms,  with or without * modification,  are permitted provided that the following conditions * are met:  (1) Redistributions of source code must retain the  above * copyright  notice,  this  list  of  conditions  and  the  following * disclaimer.  (2) Redistributions in binary form must reproduce  the * above  copyright notice,  this list of conditions and the following * disclaimer in the  documentation  and/or other  materials  provided * with  the  distribution.  (3) All advertising materials  mentioning * features or  use  of  this  software  must  display  the  following * acknowledgement:  ``This  product  includes  software  developed by * Version Technology.''  Neither the name of Version  Technology  nor * the  name  of  Peter J. Nicklin  may  be used to endorse or promote * products derived from this software without specific prior  written * permission. * * THIS SOFTWARE IS PROVIDED BY VERSION TECHNOLOGY ``AS IS''  AND  ANY * EXPRESS OR IMPLIED WARRANTIES,  INCLUDING,  BUT NOT LIMITED TO, THE * IMPLIED  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL  VERSION  TECHNOLOGY  BE * LIABLE  FOR ANY DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, * OR  CONSEQUENTIAL DAMAGES   (INCLUDING,   BUT   NOT   LIMITED   TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT LIABILITY,  OR  TORT * (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING  IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE,  EVEN  IF  ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * Report problems and direct questions to nicklin@netcom.com * * $Header: mksymlink.c,v 4.10 91/11/25 19:44:59 nicklin Exp $ * * Author: Peter J. Nicklin */#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include "Mkmf.h"#include "config.h"#include "hash.h"#include "macro.h"#include "null.h"#include "path.h"#include "slist.h"#include "yesno.h"#ifdef _HasSymLinks#define NOT_SYMLINK	1		/* not a symbolic link */#define UNV_SYMLINK	2		/* unverified symbolic link */#define VER_SYMLINK	3		/* verified symbolic link */extern int errno;			/* error indicator for system calls */extern SLIST *SRCLIST;			/* source file name list */extern SLIST *HEADLIST;			/* header file name list */extern HASH *MDEFTABLE;			/* macro definition table */static int addsrctable();		/* add file to source hash table */static int addvsrctable();		/* add virtual file to hash table */static int  hashtolist();		/* convert hash table file list */static HASH *SRCTABLE = NULL;		/* source file hash table */static HASH *HDRTABLE = NULL;		/* header file hash table */static struct stat CURDIRSTAT;		/* current directory status *//* * mksymlink() creates symbolic links from foreign directories into * the current directory. Return YES if successful, otherwise NO. * * Given the following state of the current directory and a virtual path: * * ./a.c -----> dangling reference * ./b.c        ordinary file * ./c.c ----->	a/c.c *		a/d.c * ./d.c ----->	b/d.c * ./e.c ----->	b/e.c * ./f.c ----->	c/f.c * * VPATH = a b * * mksymlink() needs to delete a.c, shift the link for d.c from directory b * to directory a, and issue a warning that f.c is linked to a file in an * external directory. */mksymlink(needsrc, needhdr)	int needsrc;			/* need source file names */	int needhdr;			/* need header file names */{	char *getpath();		/* get next path */	char *vp;			/* virtual path buffer pointer */	char vpath[PATHSIZE];		/* virtual directory path buffer */	int read_dir();			/* read dir for source and headers */	struct stat statbuf;		/* virtual path stat buffer */	if ((HDRTABLE = htinit(SOURCETABLESIZE)) == NULL)		return(NO);	if ((SRCTABLE = htinit(SOURCETABLESIZE)) == NULL)		return(NO);	if (stat(CURDIR, &CURDIRSTAT) < 0)		{		pperror(CURDIR);		return(NO);		}	if (read_dir(CURDIR, addsrctable, needsrc, needhdr) == NO)		return(NO);	/*	 * merge source/header files in other directories into hash table	 * source list	 */	if (htlookup(MVPATH, MDEFTABLE) != NULL)		{		vp = htdef(MDEFTABLE);				while ((vp = getpath(vpath, vp)) != NULL)			{			if (stat(vpath, &statbuf) < 0)				{				pperror(vpath);				continue;				}			if (!S_ISDIR(statbuf.st_mode))				{				warns("(warning) %s in VPATH not a directory", vpath);				continue;				}			if (CURDIRSTAT.st_dev == statbuf.st_dev &&			    CURDIRSTAT.st_ino == statbuf.st_ino)				{				warns("(warning) current directory %s included in VPATH", vpath);				continue;				}			if (read_dir(vpath, addvsrctable, needsrc, needhdr) == NO)				return(NO);			}		}	/*	 * convert hash table source file entries to singly-linked source list	 */	if (hashtolist(SRCTABLE, SRCLIST) == NO)		{		htrm(NULL, SRCTABLE);		return(NO);		}	htrm(NULL, SRCTABLE);	/*	 * convert hash table header file entries to singly-linked header list	 */	if (hashtolist(HDRTABLE, HEADLIST) == NO)		{		htrm(NULL, HDRTABLE);		return(NO);		}	htrm(NULL, HDRTABLE);	return(YES);}/* * addsrctable() adds a file to a source/header file hash table. Returns * YES if successful, otherwise NO. */static intaddsrctable(dirname, filename, tswitch)	char *dirname;			/* directory name */	char *filename;			/* file name to add to source table */	int tswitch;			/* source/header table switch */{	char symbuf[PATHSIZE];		/* symbolic link pathname buffer */if (readlink(filename, symbuf, PATHSIZE) < 0)		{#ifdef _HasEnxioReadlinkReturn		/* ugly hack around apollo bug */		if (errno == EINVAL || errno == ENXIO)#else                if (errno == EINVAL)#endif			{			if (htinstall(filename, NULL, NOT_SYMLINK,			   (tswitch == 's') ? SRCTABLE : HDRTABLE) == NULL)				return(NO);			}		else	{			pperror(filename);			return(NO);			}		}	else	{		if (htinstall(filename, pathhead(symbuf), UNV_SYMLINK,		   (tswitch == 's') ? SRCTABLE : HDRTABLE) == NULL)			return(NO);		}	return(YES);}/* * addvsrctable() merges source/header files from directories in the virtual * path into a source or header file hash table. If a file in the current * directory is linked to a file in a yet unseen directory, then the link * is broken and reestabished to a file in the current virtual directory. * Returns YES if successful, otherwise NO. */static intaddvsrctable(dirname, filename, tswitch)	char *dirname;			/* directory name */	char *filename;			/* file name to add to source table */	int tswitch;			/* source/header table switch */{	char path[PATHSIZE];		/* path to foreign source file */	HASH *table;			/* pointer to source/header file table */	table = (tswitch == 's') ? SRCTABLE : HDRTABLE;	if (htlookup(filename, table) != NULL)		{		if (htval(table) == UNV_SYMLINK)			{			if (!EQUAL(dirname, htdef(table)))				{	/* link file from dirname */				if(unlink(filename) < 0)					{					warns("(error) failed to remove symbolic link %s", filename);					return(NO);					}				else if (symlink(pathcat(path, dirname, filename), filename) < 0)					{					pperror(filename);					return(NO);					}				else	{					char oldpath[PATHSIZE];	/* extra pathname buffer */					pathcat(oldpath, htdef(table), filename);					warn2("(warning) symbolic link %s replaced by %s", oldpath, path);					}				}			htval(table) = VER_SYMLINK;			}		else	{			warn2("(warning) duplicate file %s/%s ignored", htdef(table), filename);			}		}	else	{		if (htinstall(filename, NULL, VER_SYMLINK, table) == NULL)			return(NO);		pathcat(path, dirname, filename);		if (symlink(path, filename) < 0)			{			pperror(filename);			return(NO);			}		}	return(YES);}/* * hashtolist() converts the file entries stored in a hash table to a * singly-linked list. Also removes dangling symbolic links, and complains * about rogue links that are not in VPATH. Returns YES if successful, * otherwise NO. */static inthashtolist(table, list)	HASH *table;			/* hash table */        SLIST *list;			/* pointer to list head block */{        extern int MKSYMLINK;           /* clobber rogue links if > 1 */	htrewind(table);	while (htnext(table))		{		if (htval(table) == UNV_SYMLINK)			{			if (MKSYMLINK > 1 || !FILEXIST(htkey(table)))				{				if(unlink(htkey(table)) < 0)					{					warns("Failed to remove symbolic link %s", htkey(table));					}				}			else	{				warns("%s linked to directory not in VPATH", htkey(table));				if (slappend(htkey(table), list) == NULL)					return(NO);				}			}		else 	{			if (slappend(htkey(table), list) == NULL)				return(NO);			}		}	return(YES);}#else/* * mksymlink() dummy routine always returns NO. */mksymlink(needsrc, needhdr)	int needsrc;			/* need source file names */	int needhdr;			/* need header file names */{	warn("symbolic links not available");	return(NO);}#endif /* _HasSymLinks */

⌨️ 快捷键说明

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