本帖最后由 go4399 于 2023-11-14 11:11 编辑
使用与linux下touch一致,部分功能没有实现。支持命令行下通配符,如touch *.*
// touch.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int _dowildcard = 1; // 1 = support wildcard, 0 = not
#define CH_ATIME 1
#define CH_MTIME 2
#define CH_CTIME 4
#define TM_SET 8
static int change_times = 0;
static FILETIME atime;
static FILETIME ctime;
static FILETIME mtime;
void usage()
{
fputws(L"Usage: touch [OPTION]... FILE...\n", stdout);
fputws(L"Update the access and modification times of each FILE to the current time.\n\n\
Mandatory arguments to long options are mandatory for short options too.\n\
-a change only the access time\n\
-c change only the creation time\n\
-m change only the modification time\n\
-r FILE use this file's times instead of current time\n\
-t STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current time\n", stdout);
}
int use_reference(const wchar_t* fileName)
{
HANDLE hFile;
if (change_times & TM_SET)
{
return 0;
}
hFile = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
if (GetFileTime(hFile, &ctime, &atime, &mtime))
{
change_times |= TM_SET;
}
CloseHandle(hFile);
}
return change_times & TM_SET;
}
int use_stamp(wchar_t* opt)
{
wchar_t* p;
SYSTEMTIME st;
if (change_times & TM_SET)
{
return 0;
}
GetLocalTime(&st);
st.wMilliseconds = 0;
p = wcschr(opt, L'.');
if (p)
{
if (p[3] == 0)
{
st.wSecond = _wtoi(p + 1);
*p = 0;
}
else
{
return 0;
}
}
else
{
st.wSecond = 0;
p = opt + wcslen(opt);
}
if (p >= opt + 2)
{
p -= 2;
st.wMinute = _wtoi(p);
*p = 0;
if (p >= opt + 2)
{
p -= 2;
st.wHour = _wtoi(p);
*p = 0;
if (p >= opt + 2)
{
p -= 2;
st.wDay = _wtoi(p);
*p = 0;
if (p >= opt + 2)
{
p -= 2;
st.wMonth = _wtoi(p);
*p = 0;
if (p == opt)
{
}
else if (p == opt + 2)
{
p -= 2;
st.wYear = (st.wYear / 100) * 100 + _wtoi(p);
}
else if (p == opt + 4)
{
p -= 4;
st.wYear = _wtoi(p);
}
else
{
return 0;
}
if (SystemTimeToFileTime(&st, &ctime) && LocalFileTimeToFileTime(&ctime, &atime))
{
ctime = atime;
mtime = atime;
change_times |= TM_SET;
}
}
}
}
}
return change_times & TM_SET;
}
int use_current()
{
SYSTEMTIME st;
if (change_times & TM_SET)
{
return 0;
}
GetSystemTime(&st);
st.wMilliseconds = 0;
if (SystemTimeToFileTime(&st, &atime))
{
ctime = atime;
mtime = atime;
change_times |= TM_SET;
}
return change_times & TM_SET;
}
int touch(const wchar_t* fileName)
{
int ret = 0;
HANDLE hFile = CreateFileW(fileName, FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
if (SetFileTime(hFile, change_times & CH_CTIME ? &ctime : 0, change_times & CH_ATIME ? &atime : 0, change_times & CH_MTIME ? &mtime : 0))
{
ret = 1;
}
CloseHandle(hFile);
}
return ret;
}
int wmain(int argc, wchar_t **argv)
{
int ret = 1;
int i;
wchar_t* opt = 0;
for (i = 1; i < argc; ++i)
{
opt = argv[i];
if (opt[0] == L'-')
{
if (opt[1] != 0 && opt[2] == 0)
{
if (opt[1] == L'a')
{
change_times |= CH_ATIME;
}
else if (opt[1] == L'c')
{
change_times |= CH_CTIME;
}
else if (opt[1] == L'm')
{
change_times |= CH_MTIME;
}
else if (opt[1] == L'r')
{
i++;
if (i < argc)
{
if (!use_reference(argv[i]))
{
i = argc;
break;
}
}
}
else if (opt[1] == L't')
{
i++;
if (i < argc)
{
if (!use_stamp(argv[i]))
{
i = argc;
break;
}
}
}
else
{
i = argc;
break;
}
}
else
{
i = argc;
break;
}
}
else
{
break;
}
}
if (i == argc)
{
usage();
return 0;
}
if (!(change_times & (CH_ATIME | CH_CTIME | CH_MTIME)))
{
change_times |= CH_ATIME | CH_CTIME | CH_MTIME;
}
use_current();
for (; i < argc; ++i)
{
ret &= touch(argv[i]);
}
return ret;
}
|