/* * dopopd - pop a directory out of the directory stack * with a numeric argument just discard it. */ void /*ARGSUSED*/ dopopd(Char **v, struct command *t) { 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); 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); }
/*ARGSUSED*/ void dodirs(Char **v, struct command *c) { static const char flags[] = "plvnSLc"; int dflag = skipargs(&v, flags, ""); USE(c); if ((dflag & DIR_CLEAR) != 0) { struct directory *dp, *fdp; for (dp = dcwd->di_next; dp != dcwd; ) { fdp = dp; dp = dp->di_next; if (fdp != &dhead) dfree(fdp); } dhead.di_next = dhead.di_prev = dp; dp->di_next = dp->di_prev = &dhead; } if ((dflag & DIR_LOAD) != 0) loaddirs(*v); else if ((dflag & DIR_SAVE) != 0) recdirs(*v, 1); if (*v && (dflag & (DIR_SAVE|DIR_LOAD))) v++; if (*v != NULL || (dflag & DIR_OLD)) stderror(ERR_DIRUS, "dirs", flags, ""); if ((dflag & (DIR_CLEAR|DIR_LOAD|DIR_SAVE)) == 0 || (dflag & DIR_PRINT)) printdirs(dflag); }
/* * dodirs - list all directories in directory loop */ void /*ARGSUSED*/ dodirs(Char **v, struct command *t) { skipargs(&v, ""); if (*v != NULL) stderror(ERR_DIRUS, "dirs", ""); printdirs(); }
/*ARGSUSED*/ void dochngd(Char **v, struct command *c) { Char *cp; struct directory *dp; int dflag = skipargs(&v, "plvn", "[-|<dir>]"); USE(c); printd = 0; cp = (dflag & DIR_OLD) ? varval(STRowd) : *v; if (cp == NULL) { if (!cdtohome) stderror(ERR_NAME | ERR_TOOFEW); else if ((cp = varval(STRhome)) == STRNULL || *cp == 0) stderror(ERR_NAME | ERR_NOHOMEDIR); if (chdir(short2str(cp)) < 0) stderror(ERR_NAME | ERR_CANTCHANGE); cp = Strsave(cp); } else if ((dflag & DIR_OLD) == 0 && v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(cp)) != 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, dflag); return; } else if ((cp = dfollow(cp, dflag & DIR_OLD)) == NULL) return; dp = 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, dflag); }
/* * 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(Char **v, struct command *t) { 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 { Char *ccp; ccp = dfollow(*v); dp = xcalloc(1, sizeof(struct directory)); 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); }
/* * dochngd - implement chdir command. */ void /*ARGSUSED*/ dochngd(Char **v, struct command *t) { Char *cp; 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 = xcalloc(1, sizeof(struct directory)); 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); }
/*ARGSUSED*/ void dopopd(Char **v, struct command *c) { Char *cp; struct directory *dp, *p = NULL; int dflag = skipargs(&v, "plvn", " [-|+<n>]"); USE(c); printd = 1; cp = (dflag & DIR_OLD) ? varval(STRowd) : *v; if (cp == NULL) dp = dcwd; else if ((dflag & DIR_OLD) == 0 && v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(cp)) == 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; dfree(dp); if (dp == dcwd) { dnewcwd(p, dflag); } else { printdirs(dflag); } }
/*ARGSUSED*/ void dopushd(Char **v, struct command *c) { struct directory *dp; Char *cp; int dflag = skipargs(&v, "plvn", " [-|<dir>|+<n>]"); USE(c); printd = 1; cp = (dflag & DIR_OLD) ? varval(STRowd) : *v; if (cp == NULL) { if (adrof(STRpushdtohome)) { if ((cp = varval(STRhome)) == STRNULL || *cp == 0) stderror(ERR_NAME | ERR_NOHOMEDIR); if (chdir(short2str(cp)) < 0) stderror(ERR_NAME | ERR_CANTCHANGE); if ((cp = dfollow(cp, dflag & DIR_OLD)) == NULL) return; dp = xcalloc(sizeof(struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_prev = dcwd; dp->di_next = dcwd->di_next; dcwd->di_next = dp; dp->di_next->di_prev = dp; } else { 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 ((dflag & DIR_OLD) == 0 && v[1] != NULL) { stderror(ERR_NAME | ERR_TOOMANY); /* NOTREACHED */ return; } else if ((dp = dfind(cp)) != NULL) { char *tmp; if (chdir(tmp = short2str(dp->di_name)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); /* * kfk - 10 Feb 1984 - added new "extraction style" pushd +n */ if (adrof(STRdextract)) dextract(dp); } else { Char *ccp; if ((ccp = dfollow(cp, dflag & DIR_OLD)) == NULL) return; dp = 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, dflag); }