mirror of
https://github.com/reactos/reactos.git
synced 2024-08-21 10:53:15 +00:00
238 lines
3.7 KiB
C
238 lines
3.7 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!
|
|
*
|
|
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
|
|
* Added DIRS command.
|
|
*/
|
|
|
|
#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 *prev;
|
|
struct tagDIRENTRY *next;
|
|
LPTSTR pszPath;
|
|
} DIRENTRY, *LPDIRENTRY;
|
|
|
|
|
|
static INT nStackDepth;
|
|
static LPDIRENTRY lpStackTop;
|
|
static LPDIRENTRY lpStackBottom;
|
|
|
|
|
|
static INT
|
|
PushDirectory (LPTSTR pszPath)
|
|
{
|
|
LPDIRENTRY lpDir;
|
|
|
|
lpDir = (LPDIRENTRY)malloc (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)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;
|
|
if (lpStackTop != NULL)
|
|
lpStackTop->prev = NULL;
|
|
else
|
|
lpStackBottom = NULL;
|
|
|
|
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;
|
|
lpStackBottom = NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* destroy directory stack
|
|
*/
|
|
VOID DestroyDirectoryStack (VOID)
|
|
{
|
|
while (nStackDepth)
|
|
PopDirectory ();
|
|
}
|
|
|
|
|
|
INT GetDirectoryStackDepth (VOID)
|
|
{
|
|
return nStackDepth;
|
|
}
|
|
|
|
|
|
/*
|
|
* pushd command
|
|
*/
|
|
INT CommandPushd (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 0;
|
|
|
|
if (bChangePath)
|
|
SetCurrentDirectory (newPath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* popd command
|
|
*/
|
|
INT CommandPopd (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;
|
|
}
|
|
|
|
|
|
/*
|
|
* dirs command
|
|
*/
|
|
INT CommandDirs (LPTSTR first, LPTSTR rest)
|
|
{
|
|
LPDIRENTRY lpDir;
|
|
|
|
if (!_tcsncmp(rest, _T("/?"), 2))
|
|
{
|
|
ConOutPuts (_T("Prints the contents of the directory stack.\n"
|
|
"\n"
|
|
"DIRS"));
|
|
return 0;
|
|
}
|
|
|
|
|
|
lpDir = lpStackBottom;
|
|
|
|
if (lpDir == NULL)
|
|
{
|
|
ConOutPuts (_T("Directory stack empty"));
|
|
return 0;
|
|
}
|
|
|
|
while (lpDir != NULL)
|
|
{
|
|
ConOutPuts (lpDir->pszPath);
|
|
|
|
lpDir = lpDir->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* FEATURE_DIRECTORY_STACK */
|