/* * DIRSTACK.C - pushd / pop (directory stack) internal commands. * * * History: * * 14-Dec-1998 (Eric Kohl) * Implemented PUSHD and POPD command. * * 20-Jan-1999 (Eric Kohl) * Unicode and redirection safe! * * 20-Jan-1999 (Eric Kohl) * Added DIRS command. */ #include "precomp.h" #ifdef FEATURE_DIRECTORY_STACK typedef struct tagDIRENTRY { struct tagDIRENTRY *prev; struct tagDIRENTRY *next; TCHAR szPath[1]; } DIRENTRY, *LPDIRENTRY; static INT nStackDepth; static LPDIRENTRY lpStackTop; static LPDIRENTRY lpStackBottom; static INT PushDirectory (LPTSTR pszPath) { LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1])); if (!lpDir) { WARN("Cannot allocate memory for lpDir\n"); error_out_of_memory(); return -1; } lpDir->prev = NULL; lpDir->next = lpStackTop; if (lpStackTop == NULL) lpStackBottom = lpDir; else lpStackTop->prev = lpDir; lpStackTop = lpDir; _tcscpy(lpDir->szPath, pszPath); nStackDepth++; return nErrorLevel = 0; } static VOID PopDirectory (VOID) { LPDIRENTRY lpDir = lpStackTop; lpStackTop = lpDir->next; if (lpStackTop != NULL) lpStackTop->prev = NULL; else lpStackBottom = NULL; cmd_free (lpDir); nStackDepth--; } /* * initialize directory stack */ VOID InitDirectoryStack (VOID) { nStackDepth = 0; lpStackTop = NULL; lpStackBottom = NULL; } /* * destroy directory stack */ VOID DestroyDirectoryStack (VOID) { while (nStackDepth) PopDirectory (); } INT GetDirectoryStackDepth (VOID) { return nStackDepth; } /* * pushd command */ INT CommandPushd (LPTSTR rest) { TCHAR curPath[MAX_PATH]; if (!_tcsncmp (rest, _T("/?"), 2)) { ConOutResPuts(STRING_DIRSTACK_HELP1); return 0; } GetCurrentDirectory (MAX_PATH, curPath); if (rest[0] != _T('\0')) { if (!SetRootPath(NULL, rest)) return 1; } return PushDirectory(curPath); } /* * popd command */ INT CommandPopd (LPTSTR rest) { INT ret = 0; if (!_tcsncmp(rest, _T("/?"), 2)) { ConOutResPuts(STRING_DIRSTACK_HELP2); return 0; } if (nStackDepth == 0) return 1; ret = _tchdir(lpStackTop->szPath) != 0; PopDirectory (); return ret; } /* * dirs command */ INT CommandDirs (LPTSTR rest) { LPDIRENTRY lpDir; if (!_tcsncmp(rest, _T("/?"), 2)) { ConOutResPuts(STRING_DIRSTACK_HELP3); return 0; } nErrorLevel = 0; lpDir = lpStackBottom; if (lpDir == NULL) { ConOutResPuts(STRING_DIRSTACK_HELP4); return 0; } while (lpDir != NULL) { ConOutPuts(lpDir->szPath); lpDir = lpDir->prev; } return 0; } #endif /* FEATURE_DIRECTORY_STACK */