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