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 21 typedef struct tagDIRENTRY 22 { 23 struct tagDIRENTRY *prev; 24 struct tagDIRENTRY *next; 25 TCHAR szPath[1]; 26 } DIRENTRY, *LPDIRENTRY; 27 28 29 static INT nStackDepth; 30 static LPDIRENTRY lpStackTop; 31 static LPDIRENTRY lpStackBottom; 32 33 34 static INT 35 PushDirectory (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 61 static VOID 62 PopDirectory (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 */ 80 VOID InitDirectoryStack (VOID) 81 { 82 nStackDepth = 0; 83 lpStackTop = NULL; 84 lpStackBottom = NULL; 85 } 86 87 88 /* 89 * destroy directory stack 90 */ 91 VOID DestroyDirectoryStack (VOID) 92 { 93 while (nStackDepth) 94 PopDirectory (); 95 } 96 97 98 INT GetDirectoryStackDepth (VOID) 99 { 100 return nStackDepth; 101 } 102 103 104 /* 105 * pushd command 106 */ 107 INT 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 */ 132 INT 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 */ 154 INT 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 */ 184