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

📄 dir.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    dp = value(cp);    if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {	xfree((ptr_t) cp);	cp = Strsave(dp);	printd = 1;	return dgoto(cp);    }    (void) strcpy(ebuf, short2str(cp));    xfree((ptr_t) cp);    stderror(ERR_SYSTEM, ebuf, strerror(serrno));    return (NULL);}/* * dopushd - push new directory onto directory stack. *	with no arguments exchange top and second. *	with numeric argument (+n) bring it to top. */void/*ARGSUSED*/dopushd(v, t)    Char **v;    struct command *t;{    register struct directory *dp;    skipargs(&v, " [<dir>|+<n>]");    printd = 1;    if (*v == NULL) {	char   *tmp;	if ((dp = dcwd->di_prev) == &dhead)	    dp = dhead.di_prev;	if (dp == dcwd)	    stderror(ERR_NAME | ERR_NODIR);	if (chdir(tmp = short2str(dp->di_name)) < 0)	    stderror(ERR_SYSTEM, tmp, strerror(errno));	dp->di_prev->di_next = dp->di_next;	dp->di_next->di_prev = dp->di_prev;	dp->di_next = dcwd->di_next;	dp->di_prev = dcwd;	dcwd->di_next->di_prev = dp;	dcwd->di_next = dp;    }    else if (v[1] != NULL) {	stderror(ERR_NAME | ERR_TOOMANY);	/* NOTREACHED */	return;    }    else if ((dp = dfind(*v)) != NULL) {	char   *tmp;	if (chdir(tmp = short2str(dp->di_name)) < 0)	    stderror(ERR_SYSTEM, tmp, strerror(errno));    }    else {	register Char *ccp;	ccp = dfollow(*v);	dp = (struct directory *) xcalloc(sizeof(struct directory), 1);	dp->di_name = ccp;	dp->di_count = 0;	dp->di_prev = dcwd;	dp->di_next = dcwd->di_next;	dcwd->di_next = dp;	dp->di_next->di_prev = dp;    }    dnewcwd(dp);}/* * dfind - find a directory if specified by numeric (+n) argument */static struct directory *dfind(cp)    register Char *cp;{    register struct directory *dp;    register int i;    register Char *ep;    if (*cp++ != '+')	return (0);    for (ep = cp; Isdigit(*ep); ep++)	continue;    if (*ep)	return (0);    i = getn(cp);    if (i <= 0)	return (0);    for (dp = dcwd; i != 0; i--) {	if ((dp = dp->di_prev) == &dhead)	    dp = dp->di_prev;	if (dp == dcwd)	    stderror(ERR_NAME | ERR_DEEP);    }    return (dp);}/* * dopopd - pop a directory out of the directory stack *	with a numeric argument just discard it. */void/*ARGSUSED*/dopopd(v, t)    Char **v;    struct command *t;{    register struct directory *dp, *p = NULL;    skipargs(&v, " [+<n>]");    printd = 1;    if (*v == NULL)	dp = dcwd;    else if (v[1] != NULL) {	stderror(ERR_NAME | ERR_TOOMANY);	/* NOTREACHED */	return;    }    else if ((dp = dfind(*v)) == 0)	stderror(ERR_NAME | ERR_BADDIR);    if (dp->di_prev == &dhead && dp->di_next == &dhead)	stderror(ERR_NAME | ERR_EMPTY);    if (dp == dcwd) {	char   *tmp;	if ((p = dp->di_prev) == &dhead)	    p = dhead.di_prev;	if (chdir(tmp = short2str(p->di_name)) < 0)	    stderror(ERR_SYSTEM, tmp, strerror(errno));    }    dp->di_prev->di_next = dp->di_next;    dp->di_next->di_prev = dp->di_prev;    if (dp == dcwd)	dnewcwd(p);    else {	printdirs();    }    dfree(dp);}/* * dfree - free the directory (or keep it if it still has ref count) */voiddfree(dp)    register struct directory *dp;{    if (dp->di_count != 0) {	dp->di_next = dp->di_prev = 0;    }    else {	xfree((char *) dp->di_name);	xfree((ptr_t) dp);    }}/* * dcanon - canonicalize the pathname, removing excess ./ and ../ etc. *	we are of course assuming that the file system is standardly *	constructed (always have ..'s, directories have links) */Char   *dcanon(cp, p)    register Char *cp, *p;{    register Char *sp;    register Char *p1, *p2;	/* general purpose */    bool    slash;    Char    link[MAXPATHLEN];    char    tlink[MAXPATHLEN];    int     cc;    Char   *newcp;    /*     * christos: if the path given does not start with a slash prepend cwd. If     * cwd does not start with a path or the result would be too long abort().     */    if (*cp != '/') {	Char    tmpdir[MAXPATHLEN];	p1 = value(STRcwd);	if (p1 == NULL || *p1 != '/')	    abort();	if (Strlen(p1) + Strlen(cp) + 1 >= MAXPATHLEN)	    abort();	(void) Strcpy(tmpdir, p1);	(void) Strcat(tmpdir, STRslash);	(void) Strcat(tmpdir, cp);	xfree((ptr_t) cp);	cp = p = Strsave(tmpdir);    }    while (*p) {		/* for each component */	sp = p;			/* save slash address */	while (*++p == '/')	/* flush extra slashes */	    continue;	if (p != ++sp)	    for (p1 = sp, p2 = p; (*p1++ = *p2++) != '\0';)		continue;	p = sp;			/* save start of component */	slash = 0;	while (*++p)		/* find next slash or end of path */	    if (*p == '/') {		slash = 1;		*p = 0;		break;	    }	if (*sp == '\0')	/* if component is null */	    if (--sp == cp)	/* if path is one char (i.e. /) */		break;	    else		*sp = '\0';	else if (sp[0] == '.' && sp[1] == 0) {	    if (slash) {		for (p1 = sp, p2 = p + 1; (*p1++ = *p2++) != '\0';)		    continue;		p = --sp;	    }	    else if (--sp != cp)		*sp = '\0';	}	else if (sp[0] == '.' && sp[1] == '.' && sp[2] == 0) {	    /*	     * We have something like "yyy/xxx/..", where "yyy" can be null or	     * a path starting at /, and "xxx" is a single component. Before	     * compressing "xxx/..", we want to expand "yyy/xxx", if it is a	     * symbolic link.	     */	    *--sp = 0;		/* form the pathname for readlink */	    if (sp != cp && !adrof(STRignore_symlinks) &&		(cc = readlink(short2str(cp), tlink,			       sizeof tlink)) >= 0) {		(void) Strcpy(link, str2short(tlink));		link[cc] = '\0';		if (slash)		    *p = '/';		/*		 * Point p to the '/' in "/..", and restore the '/'.		 */		*(p = sp) = '/';		/*		 * find length of p		 */		for (p1 = p; *p1++;)		    continue;		if (*link != '/') {		    /*		     * Relative path, expand it between the "yyy/" and the		     * "/..". First, back sp up to the character past "yyy/".		     */		    while (*--sp != '/')			continue;		    sp++;		    *sp = 0;		    /*		     * New length is "yyy/" + link + "/.." and rest		     */		    p1 = newcp = (Char *) xmalloc((size_t)						(((sp - cp) + cc + (p1 - p)) *						 sizeof(Char)));		    /*		     * Copy new path into newcp		     */		    for (p2 = cp; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = link; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)			continue;		    /*		     * Restart canonicalization at expanded "/xxx".		     */		    p = sp - cp - 1 + newcp;		}		else {		    /*		     * New length is link + "/.." and rest		     */		    p1 = newcp = (Char *) xmalloc((size_t)					    ((cc + (p1 - p)) * sizeof(Char)));		    /*		     * Copy new path into newcp		     */		    for (p2 = link; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)			continue;		    /*		     * Restart canonicalization at beginning		     */		    p = newcp;		}		xfree((ptr_t) cp);		cp = newcp;		continue;	/* canonicalize the link */	    }	    *sp = '/';	    if (sp != cp)		while (*--sp != '/')		    continue;	    if (slash) {		for (p1 = sp + 1, p2 = p + 1; (*p1++ = *p2++) != '\0';)		    continue;		p = sp;	    }	    else if (cp == sp)		*++sp = '\0';	    else		*sp = '\0';	}	else {			/* normal dir name (not . or .. or nothing) */	    if (sp != cp && adrof(STRchase_symlinks) &&		!adrof(STRignore_symlinks) &&		(cc = readlink(short2str(cp), tlink,			       sizeof tlink)) >= 0) {		(void) Strcpy(link, str2short(tlink));		link[cc] = '\0';		/*		 * restore the '/'.		 */		if (slash)		    *p = '/';		/*		 * point sp to p (rather than backing up).		 */		sp = p;		/*		 * find length of p		 */		for (p1 = p; *p1++;)		    continue;		if (*link != '/') {		    /*		     * Relative path, expand it between the "yyy/" and the		     * remainder. First, back sp up to the character past		     * "yyy/".		     */		    while (*--sp != '/')			continue;		    sp++;		    *sp = 0;		    /*		     * New length is "yyy/" + link + "/.." and rest		     */		    p1 = newcp = (Char *) xmalloc((size_t)						  (((sp - cp) + cc + (p1 - p))						   * sizeof(Char)));		    /*		     * Copy new path into newcp		     */		    for (p2 = cp; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = link; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)			continue;		    /*		     * Restart canonicalization at expanded "/xxx".		     */		    p = sp - cp - 1 + newcp;		}		else {		    /*		     * New length is link + the rest		     */		    p1 = newcp = (Char *) xmalloc((size_t)					    ((cc + (p1 - p)) * sizeof(Char)));		    /*		     * Copy new path into newcp		     */		    for (p2 = link; (*p1++ = *p2++) != '\0';)			continue;		    for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)			continue;		    /*		     * Restart canonicalization at beginning		     */		    p = newcp;		}		xfree((ptr_t) cp);		cp = newcp;		continue;	/* canonicalize the link */	    }	    if (slash)		*p = '/';	}    }    /*     * fix home...     */    p1 = value(STRhome);    cc = Strlen(p1);    /*     * See if we're not in a subdir of STRhome     */    if (p1 && *p1 == '/' &&	(Strncmp(p1, cp, cc) != 0 || (cp[cc] != '/' && cp[cc] != '\0'))) {	static ino_t home_ino = -1;	static dev_t home_dev = -1;	static Char *home_ptr = NULL;	struct stat statbuf;	/*	 * Get dev and ino of STRhome	 */	if (home_ptr != p1 &&	    stat(short2str(p1), &statbuf) != -1) {	    home_dev = statbuf.st_dev;	    home_ino = statbuf.st_ino;	    home_ptr = p1;	}	/*	 * Start comparing dev & ino backwards	 */	p2 = Strcpy(link, cp);	for (sp = NULL; *p2 && stat(short2str(p2), &statbuf) != -1;) {	    if (statbuf.st_dev == home_dev &&		statbuf.st_ino == home_ino) {		sp = (Char *) - 1;		break;	    }	    if ((sp = Strrchr(p2, '/')) != NULL)		*sp = '\0';	}	/*	 * See if we found it	 */	if (*p2 && sp == (Char *) -1) {	    /*	     * Use STRhome to make '~' work	     */	    newcp = Strspl(p1, cp + Strlen(p2));	    xfree((ptr_t) cp);	    cp = newcp;	}    }    return cp;}/* * dnewcwd - make a new directory in the loop the current one */static voiddnewcwd(dp)    register struct directory *dp;{    dcwd = dp;    dset(dcwd->di_name);    if (printd && !(adrof(STRpushdsilent)))	printdirs();}

⌨️ 快捷键说明

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