home *** CD-ROM | disk | FTP | other *** search
- /* vi:tabstop=4:shiftwidth=4:smartindent
- *
- * chdir.c - functions to do with changing directory
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "psh.h"
-
- /* Reads system variables
- */
- extern char *osgetenv(char *);
-
- /* Directory stack for pushd/popd
- */
- static char *dirstack[MAXDIRS];
- static int dirptr = -1;
-
- /* Does cd(name). If the chdir() doesn't work, then start looking
- * through the variable CDPATH to try and find a success.
- * returns 0 for success, 1 for fail.
- */
- static int do_cd(char *name)
- {
- char *cdpath;
- char *dir;
- char tmp[MAXLEN];
-
- /* Try to do the cd
- */
- if (chdir(name))
- {
- /* Try using CDPATH
- */
- cdpath = osgetenv("CDPATH");
-
- /* If CDPATH is set then
- */
- if (cdpath)
- {
- /* Split it up on spaces
- */
- while (dir = strtok(cdpath, " "))
- {
- cdpath = NULL;
- sprintf(tmp, "%s/%s", dir, name);
- /* Try to cd. If the chdir works, then
- * print where you've got to and return
- */
- DEBUG(printf("Trying %s\n", tmp);)
- if (!chdir(tmp))
- {
- puts(tmp);
- return 0;
- }
- }
- /* All entries in CDPATH failed. Try one more time
- * to chdir to the original name. This makes sure that
- * the errno is set to the original error
- */
- if (chdir(name))
- {
- return 1;
- }
- }
- else
- {
- return 1;
- }
- }
- return 0;
- }
-
- /* The "cd" command
- */
- int sh_cd(int argc, char **argv)
- {
- int do_cd(char *name);
-
- if (argc > 2)
- {
- fprintf(stderr, "Usage: cd <dir>\n");
- return 1;
- }
-
- if (do_cd(argv[1]))
- {
- perror("cd");
- }
-
- return 0;
- }
-
- /* List directories on the directory stack.
- * "\\" is always on the stack, as this allows you
- * to do popd repeatedly to swap directoried between
- * CSD and PSD.
- */
- int sh_dirs(int argc, char **argv)
- {
- int i;
-
- if (argc != 1)
- {
- fprintf(stderr, "Usage: dirs\n");
- return 1;
- }
-
- for (i=dirptr; i>=0; i--)
- {
- printf("%s ", dirstack[i]);
- }
- printf("\\\n");
- return 0;
- }
-
- /* The pushd command.
- * Places the current directory on the stack and cd's to the
- * new directory, using CDPATH
- */
- int sh_pushd(int argc, char **argv)
- {
- char tmp[MAXLEN];
-
- if (argc != 2)
- {
- fprintf(stderr, "Usage: pushd dir\n");
- return 1;
- }
- if (dirptr == MAXDIRS-1)
- {
- fprintf(stderr, "Directory stack full\n");
- return 1;
- }
- getcwd(tmp, MAXLEN);
- if (do_cd(argv[1]))
- {
- perror("pushd");
- return 1;
- }
- dirstack[++dirptr] = strdup(tmp);
- sh_dirs(1, NULL);
- return 0;
- }
-
- /* The popd command.
- * Pops a directory off the stack and cd's to it.
- * If the stack is empty, then do chdir("\\") to return
- * to the PSD.
- */
- int sh_popd(int argc, char **argv)
- {
- int r;
-
- if (argc != 1)
- {
- fprintf(stderr, "Usage: popd\n");
- return 1;
- }
- if (dirptr > -1)
- {
- r = chdir(dirstack[dirptr]);
- free(dirstack[dirptr--]);
- }
- else
- {
- r = chdir("\\");
- }
- if (r)
- {
- perror("popd");
- return 1;
- }
-
- sh_dirs(1, NULL);
- return 0;
- }
-