mirror of
https://github.com/reactos/reactos.git
synced 2024-09-06 19:02:32 +00:00
181 lines
2.8 KiB
C
181 lines
2.8 KiB
C
![]() |
/*
|
||
|
* DIRSTACK.C - pushd / pop (directory stack) internal commands.
|
||
|
*
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 14-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
|
||
|
* Implemented PUSHD and POPD command.
|
||
|
*
|
||
|
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
|
||
|
* Unicode and redirection safe!
|
||
|
*/
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#ifdef FEATURE_DIRECTORY_STACK
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <tchar.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "cmd.h"
|
||
|
|
||
|
|
||
|
typedef struct tagDIRENTRY
|
||
|
{
|
||
|
struct tagDIRENTRY *next;
|
||
|
LPTSTR pszPath;
|
||
|
} DIRENTRY, *LPDIRENTRY;
|
||
|
|
||
|
|
||
|
static INT nStackDepth;
|
||
|
static LPDIRENTRY lpStackTop;
|
||
|
|
||
|
|
||
|
static INT
|
||
|
PushDirectory (LPTSTR pszPath)
|
||
|
{
|
||
|
LPDIRENTRY lpDir;
|
||
|
|
||
|
lpDir = (LPDIRENTRY)malloc (sizeof (DIRENTRY));
|
||
|
if (!lpDir)
|
||
|
{
|
||
|
error_out_of_memory ();
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
lpDir->next = (lpStackTop) ? lpStackTop : NULL;
|
||
|
lpStackTop = lpDir;
|
||
|
|
||
|
lpDir->pszPath = (LPTSTR)malloc ((_tcslen(pszPath)+1)*sizeof(TCHAR));
|
||
|
if (!lpDir->pszPath)
|
||
|
{
|
||
|
free (lpDir);
|
||
|
error_out_of_memory ();
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
_tcscpy (lpDir->pszPath, pszPath);
|
||
|
|
||
|
nStackDepth++;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static VOID
|
||
|
PopDirectory (VOID)
|
||
|
{
|
||
|
LPDIRENTRY lpDir;
|
||
|
|
||
|
if (nStackDepth == 0)
|
||
|
return;
|
||
|
|
||
|
lpDir = lpStackTop;
|
||
|
lpStackTop = lpDir->next;
|
||
|
free (lpDir->pszPath);
|
||
|
free (lpDir);
|
||
|
|
||
|
nStackDepth--;
|
||
|
}
|
||
|
|
||
|
|
||
|
static VOID
|
||
|
GetDirectoryStackTop (LPTSTR pszPath)
|
||
|
{
|
||
|
if (lpStackTop)
|
||
|
_tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH);
|
||
|
else
|
||
|
*pszPath = _T('\0');
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* initialize directory stack
|
||
|
*/
|
||
|
VOID InitDirectoryStack (VOID)
|
||
|
{
|
||
|
nStackDepth = 0;
|
||
|
lpStackTop = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* destroy directory stack
|
||
|
*/
|
||
|
VOID DestroyDirectoryStack (VOID)
|
||
|
{
|
||
|
while (nStackDepth)
|
||
|
PopDirectory ();
|
||
|
}
|
||
|
|
||
|
|
||
|
INT GetDirectoryStackDepth (VOID)
|
||
|
{
|
||
|
return nStackDepth;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* pushd command
|
||
|
*/
|
||
|
INT cmd_pushd (LPTSTR first, LPTSTR rest)
|
||
|
{
|
||
|
TCHAR curPath[MAX_PATH];
|
||
|
TCHAR newPath[MAX_PATH];
|
||
|
BOOL bChangePath = FALSE;
|
||
|
|
||
|
if (!_tcsncmp (rest, _T("/?"), 2))
|
||
|
{
|
||
|
ConOutPuts (_T("Stores the current directory for use by the POPD command, then\n"
|
||
|
"changes to the specified directory.\n\n"
|
||
|
"PUSHD [path | ..]\n\n"
|
||
|
" path Specifies the directory to make the current directory"));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (rest[0] != _T('\0'))
|
||
|
{
|
||
|
GetFullPathName (rest, MAX_PATH, newPath, NULL);
|
||
|
bChangePath = IsValidPathName (newPath);
|
||
|
}
|
||
|
|
||
|
GetCurrentDirectory (MAX_PATH, curPath);
|
||
|
if (PushDirectory (curPath))
|
||
|
return -1;
|
||
|
|
||
|
if (bChangePath)
|
||
|
SetCurrentDirectory (newPath);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* popd command
|
||
|
*/
|
||
|
INT cmd_popd (LPTSTR first, LPTSTR rest)
|
||
|
{
|
||
|
TCHAR szPath[MAX_PATH];
|
||
|
|
||
|
if (!_tcsncmp(rest, _T("/?"), 2))
|
||
|
{
|
||
|
ConOutPuts (_T("Changes to the directory stored by the PUSHD command.\n\n"
|
||
|
"POPD"));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (GetDirectoryStackDepth () == 0)
|
||
|
return 0;
|
||
|
|
||
|
GetDirectoryStackTop (szPath);
|
||
|
PopDirectory ();
|
||
|
|
||
|
SetCurrentDirectory (szPath);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#endif /* FEATURE_DIRECTORY_STACK */
|