[TFTPD] Fix compilation, and use the #define MAX_SERVERS where needed instead of...
[reactos.git] / base / shell / cmd / dirstack.c
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 error_out_of_memory ();
41 return -1;
42 }
43
44 lpDir->prev = NULL;
45 lpDir->next = lpStackTop;
46 if (lpStackTop == NULL)
47 lpStackBottom = lpDir;
48 else
49 lpStackTop->prev = lpDir;
50 lpStackTop = lpDir;
51
52 _tcscpy(lpDir->szPath, pszPath);
53
54 nStackDepth++;
55
56 return nErrorLevel = 0;
57 }
58
59
60 static VOID
61 PopDirectory (VOID)
62 {
63 LPDIRENTRY lpDir = lpStackTop;
64 lpStackTop = lpDir->next;
65 if (lpStackTop != NULL)
66 lpStackTop->prev = NULL;
67 else
68 lpStackBottom = NULL;
69
70 cmd_free (lpDir);
71
72 nStackDepth--;
73 }
74
75
76 /*
77 * initialize directory stack
78 */
79 VOID InitDirectoryStack (VOID)
80 {
81 nStackDepth = 0;
82 lpStackTop = NULL;
83 lpStackBottom = NULL;
84 }
85
86
87 /*
88 * destroy directory stack
89 */
90 VOID DestroyDirectoryStack (VOID)
91 {
92 while (nStackDepth)
93 PopDirectory ();
94 }
95
96
97 INT GetDirectoryStackDepth (VOID)
98 {
99 return nStackDepth;
100 }
101
102
103 /*
104 * pushd command
105 */
106 INT CommandPushd (LPTSTR rest)
107 {
108 TCHAR curPath[MAX_PATH];
109
110 if (!_tcsncmp (rest, _T("/?"), 2))
111 {
112 ConOutResPuts(STRING_DIRSTACK_HELP1);
113 return 0;
114 }
115
116 GetCurrentDirectory (MAX_PATH, curPath);
117
118 if (rest[0] != _T('\0'))
119 {
120 if (!SetRootPath(NULL, rest))
121 return 1;
122 }
123
124 return PushDirectory(curPath);
125 }
126
127
128 /*
129 * popd command
130 */
131 INT CommandPopd (LPTSTR rest)
132 {
133 INT ret = 0;
134 if (!_tcsncmp(rest, _T("/?"), 2))
135 {
136 ConOutResPuts(STRING_DIRSTACK_HELP2);
137 return 0;
138 }
139
140 if (nStackDepth == 0)
141 return 1;
142
143 ret = _tchdir(lpStackTop->szPath) != 0;
144 PopDirectory ();
145
146 return ret;
147 }
148
149
150 /*
151 * dirs command
152 */
153 INT CommandDirs (LPTSTR rest)
154 {
155 LPDIRENTRY lpDir;
156
157 if (!_tcsncmp(rest, _T("/?"), 2))
158 {
159 ConOutResPuts(STRING_DIRSTACK_HELP3);
160 return 0;
161 }
162
163 nErrorLevel = 0;
164
165 lpDir = lpStackBottom;
166
167 if (lpDir == NULL)
168 {
169 ConOutResPuts(STRING_DIRSTACK_HELP4);
170 return 0;
171 }
172
173 while (lpDir != NULL)
174 {
175 ConOutPuts(lpDir->szPath);
176 lpDir = lpDir->prev;
177 }
178
179 return 0;
180 }
181
182 #endif /* FEATURE_DIRECTORY_STACK */