Reactos
at listview 183 lines 2.9 kB view raw
1/* 2 * DIRSTACK.C - pushd / pop (directory stack) internal commands. 3 * 4 * 5 * History: 6 * 7 * 14-Dec-1998 (Eric Kohl) 8 * Implemented PUSHD and POPD command. 9 * 10 * 20-Jan-1999 (Eric Kohl) 11 * Unicode and redirection safe! 12 * 13 * 20-Jan-1999 (Eric Kohl) 14 * Added DIRS command. 15 */ 16 17#include "precomp.h" 18 19#ifdef FEATURE_DIRECTORY_STACK 20 21typedef struct tagDIRENTRY 22{ 23 struct tagDIRENTRY *prev; 24 struct tagDIRENTRY *next; 25 TCHAR szPath[1]; 26} DIRENTRY, *LPDIRENTRY; 27 28 29static INT nStackDepth; 30static LPDIRENTRY lpStackTop; 31static LPDIRENTRY lpStackBottom; 32 33 34static INT 35PushDirectory (LPTSTR pszPath) 36{ 37 LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1])); 38 if (!lpDir) 39 { 40 WARN("Cannot allocate memory for lpDir\n"); 41 error_out_of_memory(); 42 return -1; 43 } 44 45 lpDir->prev = NULL; 46 lpDir->next = lpStackTop; 47 if (lpStackTop == NULL) 48 lpStackBottom = lpDir; 49 else 50 lpStackTop->prev = lpDir; 51 lpStackTop = lpDir; 52 53 _tcscpy(lpDir->szPath, pszPath); 54 55 nStackDepth++; 56 57 return nErrorLevel = 0; 58} 59 60 61static VOID 62PopDirectory (VOID) 63{ 64 LPDIRENTRY lpDir = lpStackTop; 65 lpStackTop = lpDir->next; 66 if (lpStackTop != NULL) 67 lpStackTop->prev = NULL; 68 else 69 lpStackBottom = NULL; 70 71 cmd_free (lpDir); 72 73 nStackDepth--; 74} 75 76 77/* 78 * initialize directory stack 79 */ 80VOID InitDirectoryStack (VOID) 81{ 82 nStackDepth = 0; 83 lpStackTop = NULL; 84 lpStackBottom = NULL; 85} 86 87 88/* 89 * destroy directory stack 90 */ 91VOID DestroyDirectoryStack (VOID) 92{ 93 while (nStackDepth) 94 PopDirectory (); 95} 96 97 98INT GetDirectoryStackDepth (VOID) 99{ 100 return nStackDepth; 101} 102 103 104/* 105 * pushd command 106 */ 107INT CommandPushd (LPTSTR rest) 108{ 109 TCHAR curPath[MAX_PATH]; 110 111 if (!_tcsncmp (rest, _T("/?"), 2)) 112 { 113 ConOutResPuts(STRING_DIRSTACK_HELP1); 114 return 0; 115 } 116 117 GetCurrentDirectory (MAX_PATH, curPath); 118 119 if (rest[0] != _T('\0')) 120 { 121 if (!SetRootPath(NULL, rest)) 122 return 1; 123 } 124 125 return PushDirectory(curPath); 126} 127 128 129/* 130 * popd command 131 */ 132INT CommandPopd (LPTSTR rest) 133{ 134 INT ret = 0; 135 if (!_tcsncmp(rest, _T("/?"), 2)) 136 { 137 ConOutResPuts(STRING_DIRSTACK_HELP2); 138 return 0; 139 } 140 141 if (nStackDepth == 0) 142 return 1; 143 144 ret = _tchdir(lpStackTop->szPath) != 0; 145 PopDirectory (); 146 147 return ret; 148} 149 150 151/* 152 * dirs command 153 */ 154INT CommandDirs (LPTSTR rest) 155{ 156 LPDIRENTRY lpDir; 157 158 if (!_tcsncmp(rest, _T("/?"), 2)) 159 { 160 ConOutResPuts(STRING_DIRSTACK_HELP3); 161 return 0; 162 } 163 164 nErrorLevel = 0; 165 166 lpDir = lpStackBottom; 167 168 if (lpDir == NULL) 169 { 170 ConOutResPuts(STRING_DIRSTACK_HELP4); 171 return 0; 172 } 173 174 while (lpDir != NULL) 175 { 176 ConOutPuts(lpDir->szPath); 177 lpDir = lpDir->prev; 178 } 179 180 return 0; 181} 182 183#endif /* FEATURE_DIRECTORY_STACK */