⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dir.c

📁 PocketCMD是与pocketconsole配合实用的命令行解释器(Shell)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: dir.c,v 1.1.1.1 2004/02/15 23:24:43 pfalcon Exp $ * *  DIR.C - dir internal command. * * *  History: * *    01/29/97 (Tim Norman) *        started. * *    06/13/97 (Tim Norman) *      Fixed code. * *    07/12/97 (Tim Norman) *        Fixed bug that caused the root directory to be unlistable * *    07/12/97 (Marc Desrochers) *        Changed to use maxx, maxy instead of findxy() * *    06/08/98 (Rob Lake) *        Added compatibility for /w in dir * *    06/09/98 (Rob Lake) *        Compatibility for dir/s started *        Tested that program finds directories off root fine * *    06/10/98 (Rob Lake) *        do_recurse saves the cwd and also stores it in Root *        build_tree adds the cwd to the beginning of its' entries *        Program runs fine, added print_tree -- works fine.. as EXE, *        program won't work properly as COM. * *    06/11/98 (Rob Lake) *        Found problem that caused COM not to work * *    06/12/98 (Rob Lake) *        debugged... *        added free mem routine * *    06/13/98 (Rob Lake) *        debugged the free mem routine *        debugged whole thing some more *        Notes: *        ReadDir stores Root name and _Read_Dir does the hard work *        PrintDir prints Root and _Print_Dir does the hard work *        KillDir kills Root _after_ _Kill_Dir does the hard work *        Integrated program into DIR.C(this file) and made some same *        changes throughout * *    06/14/98 (Rob Lake) *        Cleaned up code a bit, added comments * *    06/16/98 (Rob Lake) *        Added error checking to my previously added routines * *    06/17/98 (Rob Lake) *        Rewrote recursive functions, again! Most other recursive *        functions are now obsolete -- ReadDir, PrintDir, _Print_Dir, *        KillDir and _Kill_Dir.  do_recurse does what PrintDir did *        and _Read_Dir did what it did before along with what _Print_Dir *        did.  Makes /s a lot faster! *        Reports 2 more files/dirs that MS-DOS actually reports *        when used in root directory(is this because dir defaults *        to look for read only files?) *        Added support for /b, /a and /l *        Made error message similar to DOS error messages *        Added help screen * *    06/20/98 (Rob Lake) *        Added check for /-(switch) to turn off previously defined *        switches. *        Added ability to check for DIRCMD in environment and *        process it * *    06/21/98 (Rob Lake) *        Fixed up /B *        Now can dir *.ext/X, no spaces! * *    06/29/98 (Rob Lake) *        error message now found in command.h * *    07/08/1998 (John P. Price) *        removed extra returns; closer to MSDOS *        fixed wide display so that an extra return is not displayed *        when there is five filenames in the last line. * *    07/12/98 (Rob Lake) *        Changed error messages * *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>) *        added config.h include * * *    04-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Converted source code to Win32, except recursive dir ("dir /s"). * *    10-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Fixed recursive dir ("dir /s"). * *    14-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Converted to Win32 directory functions and *        fixed some output bugs. There are still some more ;) * *    10-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Added "/N" and "/4" options, "/O" is a dummy. *        Added locale support. * *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Redirection safe! * *    01-Mar-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>) *        Replaced all runtime io functions by their Win32 counterparts. *   *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>) *        dir /s now works in deeper trees */#include "config.h"#ifdef INCLUDE_CMD_DIR#include "cmd.h"/* flag definitions */enum{	DIR_RECURSE = 0x0001,	DIR_PAGE    = 0x0002,	DIR_WIDE    = 0x0004,        /* Rob Lake */	DIR_BARE    = 0x0008,        /* Rob Lake */	DIR_ALL     = 0x0010,        /* Rob Lake */	DIR_LWR     = 0x0020,        /* Rob Lake */	DIR_SORT    = 0x0040,        /* /O sort */	DIR_NEW     = 0x0080,        /* /N new style */	DIR_FOUR    = 0x0100         /* /4 four digit year */};/* Globally save the # of dirs, files and bytes, * probabaly later pass them to functions. Rob Lake  */static ULONG recurse_dir_cnt;static ULONG recurse_file_cnt;static ULARGE_INTEGER recurse_bytes;/* * help * * displays help screen for dir * Rob Lake */static VOID Help (VOID){	ConOutPuts (_T("Displays a list of files and subdirectories in a directory.\n")		_T("\n")       _T("DIR [drive:][path][filename] [/A] [/B] [/L] [/N] [/S] [/P] [/W] [/4]\n")       _T("\n")       _T("  [drive:][path][filename]\n")       _T("              Specifies drive, directory, and/or files to list.\n")       _T("\n")       _T("  /A          Displays files with HIDDEN SYSTEM attributes\n")       _T("              default is ARCHIVE and READ ONLY\n")       _T("  /B          Uses bare format (no heading information or summary).\n")       _T("  /L          Uses lowercase.\n")       _T("  /N          New long list format where filenames are on the far right.\n")       _T("  /S          Displays files in specified directory and all subdirectories\n")       _T("  /P          Pauses after each screen full\n")       _T("  /W          Prints in wide format\n")       _T("  /4          Display four digit years.\n")       _T("\n")       _T("Switches may be present in the DIRCMD environment variable.  Use\n")       _T("of the - (hyphen) can turn off defined swtiches.  Ex. /-W would\n")       _T("turn off printing in wide format.\n")      );}/* * DirReadParam * * read the parameters from the command line */static BOOLDirReadParam (LPTSTR line, LPTSTR *param, LPDWORD lpFlags){	INT slash = 0;	if (!line)		return TRUE;	*param = NULL;	/* scan the command line, processing switches */	while (*line)	{		/* process switch */		if (*line == _T('/') || slash)		{			if (!slash)				line++;			slash = 0;			if (*line == _T('-'))			{				line++;				if (_totupper (*line) == _T('S'))					*lpFlags &= ~DIR_RECURSE;				else if (_totupper (*line) == _T('P'))					*lpFlags &= ~DIR_PAGE;				else if (_totupper (*line) == _T('W'))					*lpFlags &= ~DIR_WIDE;				else if (_totupper (*line) == _T('B'))					*lpFlags &= ~DIR_BARE;				else if (_totupper (*line) == _T('A'))					*lpFlags &= ~DIR_ALL;				else if (_totupper (*line) == _T('L'))					*lpFlags &= ~DIR_LWR;				else if (_totupper (*line) == _T('N'))					*lpFlags &= ~DIR_NEW;				else if (_totupper (*line) == _T('O'))					*lpFlags &= ~DIR_SORT;				else if (_totupper (*line) == _T('4'))					*lpFlags &= ~DIR_FOUR;				else				{					error_invalid_switch ((TCHAR)_totupper (*line));					return FALSE;				}				line++;				continue;			}			else			{				if (_totupper (*line) == _T('S'))					*lpFlags |= DIR_RECURSE;				else if (_totupper (*line) == _T('P'))					*lpFlags |= DIR_PAGE;				else if (_totupper (*line) == _T('W'))					*lpFlags |= DIR_WIDE;				else if (_totupper (*line) == _T('B'))					*lpFlags |= DIR_BARE;				else if (_totupper (*line) == _T('A'))					*lpFlags |= DIR_ALL;				else if (_totupper (*line) == _T('L'))					*lpFlags |= DIR_LWR;				else if (_totupper (*line) == _T('N'))					*lpFlags |= DIR_NEW;				else if (_totupper (*line) == _T('O'))					*lpFlags |= DIR_SORT;				else if (_totupper (*line) == _T('4'))					*lpFlags |= DIR_FOUR;				else if (*line == _T('?'))				{					Help();					return FALSE;				}				else				{					error_invalid_switch ((TCHAR)_totupper (*line));					return FALSE;				}				line++;				continue;			}		}		/* process parameter */		if (!_istspace (*line))		{			if (*param)			{				error_too_many_parameters (*param);				return FALSE;			}			*param = line;			/* skip to end of line or next whitespace or next / */			while (*line && !_istspace (*line) && *line != _T('/'))				line++;			/* if end of line, return */			if (!*line)				return TRUE;			/* if parameter, remember to process it later */			if (*line == _T('/'))				slash = 1;			*line++ = 0;			continue;		}		line++;	}	if (slash)	{		error_invalid_switch ((TCHAR)_totupper (*line));		return FALSE;	}	return TRUE;}/* * ExtendFilespec * * extend the filespec, possibly adding wildcards */static VOIDExtendFilespec (LPTSTR file){	INT len = 0;	if (!file)		return;	/* if no file spec, change to "*.*" */	if (*file == _T('\0'))	{		_tcscpy (file, _T("*.*"));		return;	}	/* if starts with . add * in front */	if (*file == _T('.'))	{		memmove (&file[1], &file[0], (_tcslen (file) + 1) * sizeof(TCHAR));		file[0] = _T('*');	}	/* if no . add .* */	if (!_tcschr (file, _T('.')))	{		_tcscat (file, _T(".*"));		return;	}	/* if last character is '.' add '*' */	len = _tcslen (file);	if (file[len - 1] == _T('.'))	{		_tcscat (file, _T("*"));		return;	}}/* * dir_parse_pathspec * * split the pathspec into drive, directory, and filespec */static INTDirParsePathspec (LPTSTR szPathspec, LPTSTR szPath, LPTSTR szFilespec){	TCHAR  szOrigPath[MAX_PATH];	LPTSTR start;	LPTSTR tmp;	INT    i;	BOOL   bWildcards = FALSE;	GetCurrentDirectory (MAX_PATH, szOrigPath);	/* get the drive and change to it */	if (szPathspec[1] == _T(':'))	{		TCHAR szRootPath[] = _T("A:");		szRootPath[0] = szPathspec[0];		start = szPathspec + 2;		SetCurrentDirectory (szRootPath);	}	else	{		start = szPathspec;	}	/* check for wildcards */	for (i = 0; szPathspec[i]; i++)	{		if (szPathspec[i] == _T('*') || szPathspec[i] == _T('?'))			bWildcards = TRUE;	}	/* check if this spec is a directory */	if (!bWildcards)	{		if (SetCurrentDirectory (szPathspec))		{			_tcscpy (szFilespec, _T("*.*"));			if (!GetCurrentDirectory (MAX_PATH, szPath))			{				szFilespec[0] = _T('\0');				SetCurrentDirectory (szOrigPath);				error_out_of_memory();				return 1;			}			SetCurrentDirectory (szOrigPath);			return 0;		}	}	/* find the file spec */	tmp = _tcsrchr (start, _T('\\'));	/* if no path is specified */	if (!tmp)	{		_tcscpy (szFilespec, start);		ExtendFilespec (szFilespec);		if (!GetCurrentDirectory (MAX_PATH, szPath))		{			szFilespec[0] = _T('\0');			SetCurrentDirectory (szOrigPath);			error_out_of_memory();			return 1;		}		SetCurrentDirectory (szOrigPath);		return 0;	}	/* get the filename */	_tcscpy (szFilespec, tmp+1);	ExtendFilespec (szFilespec);	*tmp = _T('\0');	/* change to this directory and get its full name */	if (!SetCurrentDirectory (start))	{		*tmp = _T('\\');		szFilespec[0] = _T('\0');		SetCurrentDirectory (szOrigPath);		error_path_not_found ();		return 1;	}	if (!GetCurrentDirectory (MAX_PATH, szPath))	{		*tmp = _T('\\');		szFilespec[0] = _T('\0');		SetCurrentDirectory (szOrigPath);		error_out_of_memory ();		return 1;	}	*tmp = _T('\\');	SetCurrentDirectory (szOrigPath);	return 0;}/* * incline * * increment our line if paginating, display message at end of screen */static BOOLIncLine (LPINT pLine, DWORD dwFlags){	if (!(dwFlags & DIR_PAGE))		return FALSE;	(*pLine)++;	if (*pLine >= (int)maxy - 2)	{		*pLine = 0;		return (PagePrompt () == PROMPT_BREAK);	}	return FALSE;}/* * PrintDirectoryHeader * * print the header for the dir command */static BOOLPrintDirectoryHeader (LPTSTR szPath, LPINT pLine, DWORD dwFlags){#ifndef _WIN32	TCHAR szRootName[] = _T("A:\\");	TCHAR szVolName[80];	DWORD dwSerialNr;	if (dwFlags & DIR_BARE)		return TRUE;	/* get the media ID of the drive */	szRootName[0] = szPath[0];	if (!GetVolumeInformation (szRootName, szVolName, 80, &dwSerialNr,	                           NULL, NULL, NULL, 0))	{c		error_invalid_drive();		return FALSE;	}	/* print drive info */	ConOutPrintf (_T(" Volume in drive %c"), szRootName[0]);	if (szVolName[0] != _T('\0'))		ConOutPrintf (_T(" is %s\n"), szVolName);	else		ConOutPrintf (_T(" has no label\n"));	if (IncLine (pLine, dwFlags))		return FALSE;	/* print the volume serial number if the return was successful */	ConOutPrintf (_T(" Volume Serial Number is %04X-%04X\n"),	              HIWORD(dwSerialNr),	              LOWORD(dwSerialNr));	if (IncLine (pLine, dwFlags))		return FALSE;#endif	return TRUE;}/* * convert * * insert commas into a number */static INTConvertULong (ULONG num, LPTSTR des, INT len){	TCHAR temp[32];	INT c = 0;	INT n = 0;	if (num == 0)	{		des[0] = _T('0');		des[1] = _T('\0');		n = 1;	}	else	{		temp[31] = 0;		while (num > 0)		{			if (((c + 1) % (nNumberGroups + 1)) == 0)				temp[30 - c++] = cThousandSeparator;			temp[30 - c++] = (TCHAR)(num % 10) + _T('0');			num /= 10;		}		for (n = 0; n <= c; n++)			des[n] = temp[31 - c + n];	}	return n;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -