mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 12:26:32 +00:00
3f892a8d6b
Adapted from a patch by Jacob S. Preciado. Bring also the code suggestions emitted during review.
184 lines
2.8 KiB
C
184 lines
2.8 KiB
C
/*
|
|
* DIRSTACK.C - pushd / pop (directory stack) internal commands.
|
|
*
|
|
*
|
|
* History:
|
|
*
|
|
* 14-Dec-1998 (Eric Kohl)
|
|
* Implemented PUSHD and POPD command.
|
|
*
|
|
* 20-Jan-1999 (Eric Kohl)
|
|
* Unicode and redirection safe!
|
|
*
|
|
* 20-Jan-1999 (Eric Kohl)
|
|
* Added DIRS command.
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#ifdef FEATURE_DIRECTORY_STACK
|
|
|
|
typedef struct tagDIRENTRY
|
|
{
|
|
struct tagDIRENTRY *prev;
|
|
struct tagDIRENTRY *next;
|
|
TCHAR szPath[1];
|
|
} DIRENTRY, *LPDIRENTRY;
|
|
|
|
|
|
static INT nStackDepth;
|
|
static LPDIRENTRY lpStackTop;
|
|
static LPDIRENTRY lpStackBottom;
|
|
|
|
|
|
static INT
|
|
PushDirectory (LPTSTR pszPath)
|
|
{
|
|
LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1]));
|
|
if (!lpDir)
|
|
{
|
|
WARN("Cannot allocate memory for lpDir\n");
|
|
error_out_of_memory();
|
|
return -1;
|
|
}
|
|
|
|
lpDir->prev = NULL;
|
|
lpDir->next = lpStackTop;
|
|
if (lpStackTop == NULL)
|
|
lpStackBottom = lpDir;
|
|
else
|
|
lpStackTop->prev = lpDir;
|
|
lpStackTop = lpDir;
|
|
|
|
_tcscpy(lpDir->szPath, pszPath);
|
|
|
|
nStackDepth++;
|
|
|
|
return nErrorLevel = 0;
|
|
}
|
|
|
|
|
|
static VOID
|
|
PopDirectory (VOID)
|
|
{
|
|
LPDIRENTRY lpDir = lpStackTop;
|
|
lpStackTop = lpDir->next;
|
|
if (lpStackTop != NULL)
|
|
lpStackTop->prev = NULL;
|
|
else
|
|
lpStackBottom = NULL;
|
|
|
|
cmd_free (lpDir);
|
|
|
|
nStackDepth--;
|
|
}
|
|
|
|
|
|
/*
|
|
* initialize directory stack
|
|
*/
|
|
VOID InitDirectoryStack (VOID)
|
|
{
|
|
nStackDepth = 0;
|
|
lpStackTop = NULL;
|
|
lpStackBottom = NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* destroy directory stack
|
|
*/
|
|
VOID DestroyDirectoryStack (VOID)
|
|
{
|
|
while (nStackDepth)
|
|
PopDirectory ();
|
|
}
|
|
|
|
|
|
INT GetDirectoryStackDepth (VOID)
|
|
{
|
|
return nStackDepth;
|
|
}
|
|
|
|
|
|
/*
|
|
* pushd command
|
|
*/
|
|
INT CommandPushd (LPTSTR rest)
|
|
{
|
|
TCHAR curPath[MAX_PATH];
|
|
|
|
if (!_tcsncmp (rest, _T("/?"), 2))
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP1);
|
|
return 0;
|
|
}
|
|
|
|
GetCurrentDirectory (MAX_PATH, curPath);
|
|
|
|
if (rest[0] != _T('\0'))
|
|
{
|
|
if (!SetRootPath(NULL, rest))
|
|
return 1;
|
|
}
|
|
|
|
return PushDirectory(curPath);
|
|
}
|
|
|
|
|
|
/*
|
|
* popd command
|
|
*/
|
|
INT CommandPopd (LPTSTR rest)
|
|
{
|
|
INT ret = 0;
|
|
if (!_tcsncmp(rest, _T("/?"), 2))
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP2);
|
|
return 0;
|
|
}
|
|
|
|
if (nStackDepth == 0)
|
|
return 1;
|
|
|
|
ret = _tchdir(lpStackTop->szPath) != 0;
|
|
PopDirectory ();
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* dirs command
|
|
*/
|
|
INT CommandDirs (LPTSTR rest)
|
|
{
|
|
LPDIRENTRY lpDir;
|
|
|
|
if (!_tcsncmp(rest, _T("/?"), 2))
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP3);
|
|
return 0;
|
|
}
|
|
|
|
nErrorLevel = 0;
|
|
|
|
lpDir = lpStackBottom;
|
|
|
|
if (lpDir == NULL)
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP4);
|
|
return 0;
|
|
}
|
|
|
|
while (lpDir != NULL)
|
|
{
|
|
ConOutPuts(lpDir->szPath);
|
|
lpDir = lpDir->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* FEATURE_DIRECTORY_STACK */
|