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

📄 link.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* $Source: /u/mark/src/pax/RCS/link.c,v $ * * $Revision: 1.2 $ * * link.c - functions for handling multiple file links  * * DESCRIPTION * *	These function manage the link chains which are used to keep track *	of outstanding links during archive reading and writing. * * AUTHOR * *	Mark H. Colburn, NAPS International (mark@jhereg.mn.org) * * Sponsored by The USENIX Association for public distribution.  * * Copyright (c) 1989 Mark H. Colburn. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice is duplicated in all such  * forms and that any documentation, advertising materials, and other  * materials related to such distribution and use acknowledge that the  * software was developed * by Mark H. Colburn and sponsored by The  * USENIX Association.  * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * $Log:	link.c,v $ * Revision 1.2  89/02/12  10:04:38  mark * 1.2 release fixes *  * Revision 1.1  88/12/23  18:02:12  mark * Initial revision *  */#ifndef lintstatic char *ident = "$Id: link.c,v 1.2 89/02/12 10:04:38 mark Exp $";static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";#endif /* ! lint *//* Headers */#include "pax.h"/* Defines *//* * Address link information base.  */#define	LINKHASH(ino)	(linkbase + (ino) % NEL(linkbase))/* * Number of array elements.  */#define	NEL(a)		(sizeof(a) / sizeof(*(a)))/* Internal Identifiers */static Link    *linkbase[256];	/* Unresolved link information *//* linkfrom - find a file to link from  * * DESCRIPTION * *	Linkfrom searches the link chain to see if there is a file in the *	link chain which has the same inode number as the file specified *	by the stat block pointed at by asb.  If a file is found, the *	name is returned to the caller, otherwise a NULL is returned. * * PARAMETERS * *	char    *name   - name of the file which we are attempting *                        to find a link for *	Stat	*asb	- stat structure of file to find a link to * * RETURNS * * 	Returns a pointer to a link structure, or NULL if unsuccessful.  * */#ifdef __STDC__Link *linkfrom(char *name, Stat *asb)#else    Link *linkfrom(name, asb)char           *name;Stat           *asb;#endif{    Link           *linkp;    Link           *linknext;    Path           *path;    Path           *pathnext;    Link          **abase;    for (linkp = *(abase = LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {	if (linkp->l_nlink == 0) {	    if (linkp->l_name) {		free((char *) linkp->l_name);	    }	    if (linknext = linkp->l_forw) {		linknext->l_back = linkp->l_back;	    }	    if (linkp->l_back) {		linkp->l_back->l_forw = linkp->l_forw;	    }	    free((char *) linkp);	    *abase = (Link *)NULL;	} else if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {	    /* 	     * check to see if a file with the name "name" exists in the 	     * chain of files which we have for this particular link	     */	    for (path = linkp->l_path; path; path = pathnext) {		if (strcmp(path->p_name, name) == 0) {		    --linkp->l_nlink;		    if (path->p_name) {			free(path->p_name);		    }		    if (pathnext = path->p_forw) {			pathnext->p_back = path->p_back;		    }		    if (path->p_back) {			path->p_back->p_forw = pathnext;		    }		    if (linkp->l_path == path) {			linkp->l_path = pathnext;		    }		    free(path);		    return (linkp);		}		pathnext = path->p_forw;	    }	    return((Link *)NULL);	} else {	    linknext = linkp->l_forw;	}    }    return ((Link *)NULL);}/* islink - determine whether a given file really a link * * DESCRIPTION * *	Islink searches the link chain to see if there is a file in the *	link chain which has the same inode number as the file specified *	by the stat block pointed at by asb.  If a file is found, a *	non-zero value is returned to the caller, otherwise a 0 is *	returned. * * PARAMETERS * *	char    *name   - name of file to check to see if it is link. *	Stat	*asb	- stat structure of file to find a link to * * RETURNS * * 	Returns a pointer to a link structure, or NULL if unsuccessful.  * */#ifdef __STDC__Link *islink(char *name, Stat *asb)#else    Link *islink(name, asb)char           *name;Stat           *asb;#endif{    Link           *linkp;    Link           *linknext;    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {	if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {	    if (strcmp(name, linkp->l_name) == 0) {		return ((Link *)NULL);	    } 	    return (linkp);	} else {	    linknext = linkp->l_forw;	}    }    return ((Link *)NULL);}/* linkto  - remember a file with outstanding links  * * DESCRIPTION * *	Linkto adds the specified file to the link chain.  Any subsequent *	calls to linkfrom which have the same inode will match the file *	just entered.  If not enough space is available to make the link *	then the item is not added to the link chain, and a NULL is *	returned to the calling function. * * PARAMETERS * *	char	*name	- name of file to remember *	Stat	*asb	- pointer to stat structure of file to remember * * RETURNS * * 	Returns a pointer to the associated link structure, or NULL when  *	linking is not possible.  * */#ifdef __STDC__Link *linkto(char *name, Stat *asb)#else    Link *linkto(name, asb)char           *name;Stat           *asb;#endif{    Link           *linkp;    Link           *linknext;    Path           *path;    Link          **abase;    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {	if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {	    if ((path = (Path *) mem_get(sizeof(Path))) == (Path *)NULL || 		(path->p_name = mem_str(name)) == (char *)NULL) {		return((Link *)NULL);	    }	    if (path->p_forw = linkp->l_path) {		if (linkp->l_path->p_forw) {		    linkp->l_path->p_forw->p_back = path;		}	    } else {		linkp->l_path = path;	    }	    path->p_back = (Path *)NULL;	    return(linkp);	} else {	    linknext = linkp->l_forw;	}    }    /*     * This is a brand new link, for which there is no other information     */    if ((asb->sb_mode & S_IFMT) == S_IFDIR	|| (linkp = (Link *) mem_get(sizeof(Link))) == (Link *)NULL	|| (linkp->l_name = mem_str(name)) == (char *)NULL) {	return ((Link *)NULL);    }    linkp->l_dev = asb->sb_dev;    linkp->l_ino = asb->sb_ino;    linkp->l_nlink = asb->sb_nlink - 1;    linkp->l_size = asb->sb_size;    linkp->l_path = (Path *)NULL;    if (linkp->l_forw = *(abase = LINKHASH(asb->sb_ino))) {	linkp->l_forw->l_back = linkp;    } else {	*abase = linkp;    }    linkp->l_back = (Link *)NULL;    return (linkp);}/* linkleft - complain about files with unseen links  * * DESCRIPTION * *	Linksleft scans through the link chain to see if there were any *	files which have outstanding links that were not processed by the *	archive.  For each file in the link chain for which there was not *	a file,  and error message is printed. */#ifdef __STDC__void linkleft(void)#else    void linkleft()#endif{    Link           *lp;    Link          **base;    for (base = linkbase; base < linkbase + NEL(linkbase); ++base) {	for (lp = *base; lp; lp = lp->l_forw) {	    if (lp->l_nlink) {		warn(lp->l_path->p_name, "Unseen link(s)");	    }	}    }}

⌨️ 快捷键说明

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