mirror of
https://github.com/reactos/reactos.git
synced 2024-06-27 16:31:30 +00:00
c49ed3a82c
- a hack in cmd_mkdir that was already obsolete a decade ago - to distinguish "echo" from "echo.", but that is the wrong way to implement this anyway. There's nothing particularly special about the period, "echo" is just one of those commands that is lenient about where its parameters begin, and when it echos a line, the first character (usually a space, but in the case of "echo." a period) is skipped. svn path=/trunk/; revision=35647
235 lines
3.2 KiB
C
235 lines
3.2 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;
|
|
LPTSTR pszPath;
|
|
} DIRENTRY, *LPDIRENTRY;
|
|
|
|
|
|
static INT nStackDepth;
|
|
static LPDIRENTRY lpStackTop;
|
|
static LPDIRENTRY lpStackBottom;
|
|
|
|
|
|
static INT
|
|
PushDirectory (LPTSTR pszPath)
|
|
{
|
|
LPDIRENTRY lpDir;
|
|
|
|
nErrorLevel = 0;
|
|
|
|
lpDir = (LPDIRENTRY)cmd_alloc (sizeof (DIRENTRY));
|
|
if (!lpDir)
|
|
{
|
|
error_out_of_memory ();
|
|
return -1;
|
|
}
|
|
|
|
lpDir->prev = NULL;
|
|
if (lpStackTop == NULL)
|
|
{
|
|
lpDir->next = NULL;
|
|
lpStackBottom = lpDir;
|
|
}
|
|
else
|
|
{
|
|
lpDir->next = lpStackTop;
|
|
lpStackTop->prev = lpDir;
|
|
}
|
|
lpStackTop = lpDir;
|
|
|
|
lpDir->pszPath = (LPTSTR)cmd_alloc ((_tcslen(pszPath)+1)*sizeof(TCHAR));
|
|
if (!lpDir->pszPath)
|
|
{
|
|
cmd_free (lpDir);
|
|
error_out_of_memory ();
|
|
return -1;
|
|
}
|
|
|
|
_tcscpy (lpDir->pszPath, pszPath);
|
|
|
|
nStackDepth++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static VOID
|
|
PopDirectory (VOID)
|
|
{
|
|
LPDIRENTRY lpDir;
|
|
|
|
nErrorLevel = 0;
|
|
|
|
if (nStackDepth == 0)
|
|
return;
|
|
|
|
lpDir = lpStackTop;
|
|
lpStackTop = lpDir->next;
|
|
if (lpStackTop != NULL)
|
|
lpStackTop->prev = NULL;
|
|
else
|
|
lpStackBottom = NULL;
|
|
|
|
cmd_free (lpDir->pszPath);
|
|
cmd_free (lpDir);
|
|
|
|
nStackDepth--;
|
|
}
|
|
|
|
|
|
static VOID
|
|
GetDirectoryStackTop (LPTSTR pszPath)
|
|
{
|
|
nErrorLevel = 0;
|
|
|
|
if (lpStackTop)
|
|
_tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH);
|
|
else
|
|
*pszPath = _T('\0');
|
|
}
|
|
|
|
|
|
/*
|
|
* 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];
|
|
TCHAR newPath[MAX_PATH];
|
|
BOOL bChangePath = FALSE;
|
|
|
|
if (!_tcsncmp (rest, _T("/?"), 2))
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP1);
|
|
return 0;
|
|
}
|
|
|
|
nErrorLevel = 0;
|
|
|
|
if (rest[0] != _T('\0'))
|
|
{
|
|
GetFullPathName (rest, MAX_PATH, newPath, NULL);
|
|
bChangePath = IsValidPathName (newPath);
|
|
}
|
|
|
|
GetCurrentDirectory (MAX_PATH, curPath);
|
|
if (PushDirectory (curPath))
|
|
return 0;
|
|
|
|
if (bChangePath)
|
|
SetCurrentDirectory (newPath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* popd command
|
|
*/
|
|
INT CommandPopd (LPTSTR rest)
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
|
|
if (!_tcsncmp(rest, _T("/?"), 2))
|
|
{
|
|
ConOutResPuts(STRING_DIRSTACK_HELP2);
|
|
return 0;
|
|
}
|
|
|
|
nErrorLevel = 0;
|
|
|
|
if (GetDirectoryStackDepth () == 0)
|
|
return 0;
|
|
|
|
GetDirectoryStackTop (szPath);
|
|
PopDirectory ();
|
|
|
|
SetCurrentDirectory (szPath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* 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->pszPath);
|
|
|
|
lpDir = lpDir->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* FEATURE_DIRECTORY_STACK */
|