Reactos
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 */