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

📄 dir.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1980, 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * 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 the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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. */#ifndef lintstatic char sccsid[] = "@(#)dir.c	8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/param.h>#include <sys/stat.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#if __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include "csh.h"#include "dir.h"#include "extern.h"/* Directory management. */static struct directory		*dfind __P((Char *));static Char	*dfollow __P((Char *));static void	 printdirs __P((void));static Char	*dgoto __P((Char *));static void	 dnewcwd __P((struct directory *));static void	 dset __P((Char *));struct directory dhead;		/* "head" of loop */int     printd;			/* force name to be printed */static int dirflag = 0;/* * dinit - initialize current working directory */voiddinit(hp)    Char   *hp;{    register char *tcp;    register Char *cp;    register struct directory *dp;    char    path[MAXPATHLEN];    static char *emsg = "csh: Trying to start from \"%s\"\n";    /* Don't believe the login shell home, because it may be a symlink */    tcp = getwd(path);		/* see ngetwd.c for System V version */    if (tcp == NULL || *tcp == '\0') {	(void) fprintf(csherr, "csh: %s\n", path);	if (hp && *hp) {	    tcp = short2str(hp);	    if (chdir(tcp) == -1)		cp = NULL;	    else		cp = hp;	    (void) fprintf(csherr, emsg, vis_str(hp));	}	else	    cp = NULL;	if (cp == NULL) {	    (void) fprintf(csherr, emsg, "/");	    if (chdir("/") == -1)		/* I am not even try to print an error message! */		xexit(1);	    cp = SAVE("/");	}    }    else {	struct stat swd, shp;	/*	 * See if $HOME is the working directory we got and use that	 */	if (hp && *hp &&	    stat(tcp, &swd) != -1 && stat(short2str(hp), &shp) != -1 &&	    swd.st_dev == shp.st_dev && swd.st_ino == shp.st_ino)	    cp = hp;	else {	    char   *cwd;	    /*	     * use PWD if we have it (for subshells)	     */	    if ((cwd = getenv("PWD")) != NULL) {		if (stat(cwd, &shp) != -1 && swd.st_dev == shp.st_dev &&		    swd.st_ino == shp.st_ino)		    tcp = cwd;	    }	    cp = dcanon(SAVE(tcp), STRNULL);	}    }    dp = (struct directory *) xcalloc(sizeof(struct directory), 1);    dp->di_name = Strsave(cp);    dp->di_count = 0;    dhead.di_next = dhead.di_prev = dp;    dp->di_next = dp->di_prev = &dhead;    printd = 0;    dnewcwd(dp);}static voiddset(dp)Char *dp;{    /*     * Don't call set() directly cause if the directory contains ` or     * other junk characters glob will fail.     */    register Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **)));    vec[0] = Strsave(dp);    vec[1] = 0;    setq(STRcwd, vec, &shvhed);    Setenv(STRPWD, dp);}#define DIR_LONG 1#define DIR_VERT 2#define DIR_LINE 4static voidskipargs(v, str)    Char ***v;    char   *str;{    Char  **n = *v, *s;    dirflag = 0;    for (n++; *n != NULL && (*n)[0] == '-'; n++)	for (s = &((*n)[1]); *s; s++)	    switch (*s) {	    case 'l':		dirflag |= DIR_LONG;		break;	    case 'v':		dirflag |= DIR_VERT;		break;	    case 'n':		dirflag |= DIR_LINE;		break;	    default:		stderror(ERR_DIRUS, vis_str(**v), str);		break;	    }    *v = n;}/* * dodirs - list all directories in directory loop */void/*ARGSUSED*/dodirs(v, t)    Char **v;    struct command *t;{    skipargs(&v, "");    if (*v != NULL)	stderror(ERR_DIRUS, "dirs", "");    printdirs();}static voidprintdirs(){    register struct directory *dp;    Char   *s, *hp = value(STRhome);    int     idx, len, cur;    if (*hp == '\0')	hp = NULL;    dp = dcwd;    idx = 0;    cur = 0;    do {	if (dp == &dhead)	    continue;	if (dirflag & DIR_VERT) {	    (void) fprintf(cshout, "%d\t", idx++);	    cur = 0;	}	if (!(dirflag & DIR_LONG) && hp != NULL && !eq(hp, STRslash) &&	    (len = Strlen(hp), Strncmp(hp, dp->di_name, len) == 0) &&	    (dp->di_name[len] == '\0' || dp->di_name[len] == '/')) 	    len = Strlen(s = (dp->di_name + len)) + 2;	else	    len = Strlen(s = dp->di_name) + 1;	cur += len;	if ((dirflag & DIR_LINE) && cur >= 80 - 1 && len < 80) {	    (void) fprintf(cshout, "\n");	    cur = len;	}	(void) fprintf(cshout, s != dp->di_name ? "~%s%c" : "%s%c",		vis_str(s), (dirflag & DIR_VERT) ? '\n' : ' ');    } while ((dp = dp->di_prev) != dcwd);    if (!(dirflag & DIR_VERT))	(void) fprintf(cshout, "\n");}voiddtildepr(home, dir)    register Char *home, *dir;{    if (!eq(home, STRslash) && prefix(home, dir))	(void) fprintf(cshout, "~%s", vis_str(dir + Strlen(home)));    else	(void) fprintf(cshout, "%s", vis_str(dir));}voiddtilde(){    struct directory *d = dcwd;    do {	if (d == &dhead)	    continue;	d->di_name = dcanon(d->di_name, STRNULL);    } while ((d = d->di_prev) != dcwd);    dset(dcwd->di_name);}/* dnormalize(): *	If the name starts with . or .. then we might need to normalize *	it depending on the symbolic link flags */Char   *dnormalize(cp)    Char   *cp;{#define UC (unsigned char)#define ISDOT(c) (UC(c)[0] == '.' && ((UC(c)[1] == '\0') || (UC(c)[1] == '/')))#define ISDOTDOT(c) (UC(c)[0] == '.' && ISDOT(&((c)[1])))    if ((unsigned char) cp[0] == '/')	return (Strsave(cp));    if (adrof(STRignore_symlinks)) {	int     dotdot = 0;	Char   *dp, *cwd;	cwd = (Char *) xmalloc((size_t) ((Strlen(dcwd->di_name) + 3) *					 sizeof(Char)));	(void) Strcpy(cwd, dcwd->di_name);	/*	 * Ignore . and count ..'s	 */	while (*cp) {	    if (ISDOT(cp)) {		if (*++cp)		    cp++;	    }	    else if (ISDOTDOT(cp)) {		dotdot++;		cp += 2;		if (*cp)		    cp++;	    }	    else		break;	}	while (dotdot > 0)	    if ((dp = Strrchr(cwd, '/'))) {		*dp = '\0';		dotdot--;	    }	    else		break;	if (*cp) {	    cwd[dotdot = Strlen(cwd)] = '/';	    cwd[dotdot + 1] = '\0';	    dp = Strspl(cwd, cp);	    xfree((ptr_t) cwd);	    return dp;	}	else {	    if (!*cwd) {		cwd[0] = '/';		cwd[1] = '\0';	    }	    return cwd;	}    }    return Strsave(cp);}/* * dochngd - implement chdir command. */void/*ARGSUSED*/dochngd(v, t)    Char **v;    struct command *t;{    register Char *cp;    register struct directory *dp;    skipargs(&v, " [<dir>]");    printd = 0;    if (*v == NULL) {	if ((cp = value(STRhome)) == NULL || *cp == 0)	    stderror(ERR_NAME | ERR_NOHOMEDIR);	if (chdir(short2str(cp)) < 0)	    stderror(ERR_NAME | ERR_CANTCHANGE);	cp = Strsave(cp);    }    else if (v[1] != NULL) {	stderror(ERR_NAME | ERR_TOOMANY);	/* NOTREACHED */	return;    }    else if ((dp = dfind(*v)) != 0) {	char   *tmp;	printd = 1;	if (chdir(tmp = short2str(dp->di_name)) < 0)	    stderror(ERR_SYSTEM, tmp, strerror(errno));	dcwd->di_prev->di_next = dcwd->di_next;	dcwd->di_next->di_prev = dcwd->di_prev;	dfree(dcwd);	dnewcwd(dp);	return;    }    else	cp = dfollow(*v);    dp = (struct directory *) xcalloc(sizeof(struct directory), 1);    dp->di_name = cp;    dp->di_count = 0;    dp->di_next = dcwd->di_next;    dp->di_prev = dcwd->di_prev;    dp->di_prev->di_next = dp;    dp->di_next->di_prev = dp;    dfree(dcwd);    dnewcwd(dp);}static Char *dgoto(cp)    Char   *cp;{    Char   *dp;    if (*cp != '/') {	register Char *p, *q;	int     cwdlen;	for (p = dcwd->di_name; *p++;)	    continue;	if ((cwdlen = p - dcwd->di_name - 1) == 1)	/* root */	    cwdlen = 0;	for (p = cp; *p++;)	    continue;	dp = (Char *) xmalloc((size_t)((cwdlen + (p - cp) + 1) * sizeof(Char)));	for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';)	    continue;	if (cwdlen)	    p[-1] = '/';	else	    p--;		/* don't add a / after root */	for (q = cp; (*p++ = *q++) != '\0';)	    continue;	xfree((ptr_t) cp);	cp = dp;	dp += cwdlen;    }    else	dp = cp;    cp = dcanon(cp, dp);    return cp;}/* * dfollow - change to arg directory; fall back on cdpath if not valid */static Char *dfollow(cp)    register Char *cp;{    register Char *dp;    struct varent *c;    char    ebuf[MAXPATHLEN];    int serrno;    cp = globone(cp, G_ERROR);    /*     * if we are ignoring symlinks, try to fix relatives now.     */    dp = dnormalize(cp);    if (chdir(short2str(dp)) >= 0) {	xfree((ptr_t) cp);	return dgoto(dp);    }    else {	xfree((ptr_t) dp);	if (chdir(short2str(cp)) >= 0)	    return dgoto(cp);	serrno = errno;    }    if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)	&& (c = adrof(STRcdpath))) {	Char  **cdp;	register Char *p;	Char    buf[MAXPATHLEN];	for (cdp = c->vec; *cdp; cdp++) {	    for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';)		continue;	    dp[-1] = '/';	    for (p = cp; (*dp++ = *p++) != '\0';)		continue;	    if (chdir(short2str(buf)) >= 0) {		printd = 1;		xfree((ptr_t) cp);		cp = Strsave(buf);		return dgoto(cp);	    }	}    }

⌨️ 快捷键说明

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