Харт Джонсон М.
Шрифт:
lsW –R C:\Projects\ls\Debug\*.obj
правильная работа программы будет нарушена, поскольку в ней самым существенным образом используется привязка каталогов к текущему каталогу. Завершенное решение (доступное на Web-сайте) анализирует абсолютные полные пути доступа к файлам и поэтому обеспечивает правильное выполнение программы и для второй команды.
Программа 3.2. lsw: вывод списка файлов и обход дерева каталогов
/* Глава 3. lsW — команда вывода списка файлов */
/* lsW [параметры] [файлы] */
#include "EvryThng.h"
BOOL TraverseDirectory(LPCTSTR, DWORD, LPBOOL);
DWORD FileType(LPWIN32_FIND_DATA);
BOOL ProcessItem(LPWIN32_FIND_DATA, DWORD, LPBOOL);
int _tmain(int argc, LPTSTR argv[]) {
BOOL Flags [MAX_OPTIONS], ok = TRUE;
TCHAR PathName [MAX_PATH +1], CurrPath [MAX_PATH + 1];
LPTSTR pSlash, pFileName;
int i, FileIndex;
FileIndex = Options(argc, argv, _T("R1"), &Flags[0], &Flags[1], NULL);
I* "Разобрать" шаблон поиска на "родительскую часть" и имя файла. */
GetCurrentDirectory(MAX_PATH, CurrPath); /* Сохранить текущий путь доступа. */
if (argc < FileIndex +1) /* Путь доступа не указан. Использовать текущий каталог. */
ok = TraverseDirectory(_T("*"), MAX_OPTIONS, Flags);
else for (i = FileIndex; i < argc; i++) {
/* Обработать все пути, указанные в командной строке. */
ok = TraverseDirectory(pFileName, MAX_OPTIONS, Flags) && ok;
SetCurrentDirectory(CurrPath);
/* Восстановить каталог. */
}
return ok ? 0 : 1;
}
static BOOL TraverseDirectory(LPCTSTR PathName, DWORD NumFlags, LPBOOL Flags)
/* Обход дерева каталогов; выполнить функцию ProcessItem для каждого случая совпадения. */
/* PathName: относительное или абсолютное имя просматриваемого каталога.*/
{
HANDLE SearchHandle;
WIN32_FIND_DATA FindData;
BOOL Recursive = Flags[0];
DWORD FType, iPass;
TCHAR CurrPath[MAX_PATH + 1];
GetCurrentDirectory(MAX_PATH, CurrPath);
for (iPass = 1; iPass <= 2; iPass++) {
/* Проход 1: вывод списка файлов. */
/* Проход 2: обход дерева каталогов (если задана опция –R). */
SearchHandle = FindFirstFile(PathName, &FindData);
do {
FType = FileType(&FindData);
/* Файл или каталог? */
if (iPass == 1) /* Вывести имя и атрибуты файла. */
ProcessItem(&FindData, MAX_OPTIONS, Flags);
if (FType == TYPE_DIR && iPass == 2 && Recursive) {
/* Обработать подкаталог. */
_tprintf(_T ("\n%s\\%s:"), CurrPath, FindData.cFileName);
/* Подготовка к обходу каталога. */
SetCurrentDirectory(FindData.cFileName);
TraverseDirectory(_T("*"), NumFlags, Flags);
/* Рекурсивный вызов. */
SetCurrentDirectory(_T(".."));
}
} while (FindNextFile(SearchHandle, &FindData));
FindClose (SearchHandle);
}
return TRUE;
}
static BOOL ProcessItem(LPWIN32_FIND_DATA pFileData, DWORD NumFlags, LPBOOL Flags)
/* Выводит список атрибутов файла или каталога. */
{
const TCHAR FileTypeChar[] = {' ', 'd'};