Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions CPP/7zip/Common/FileStreams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ CInFileStream::CInFileStream():
#endif
_info_WasLoaded(false),
SupportHardLinks(false),
StoreOldestCTime(false),
Callback(NULL),
CallbackRef(0)
{
Expand Down Expand Up @@ -436,7 +437,9 @@ Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT
*/
{
if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
if (cTime) *cTime = info.ftCreationTime;
if (cTime) *cTime = StoreOldestCTime ?
FiTime_Min3(info.ftCreationTime, info.ftLastAccessTime, info.ftLastWriteTime) :
info.ftCreationTime;
if (aTime) *aTime = info.ftLastAccessTime;
if (mTime) *mTime = info.ftLastWriteTime;
if (attrib) *attrib = info.dwFileAttributes;
Expand Down Expand Up @@ -603,7 +606,11 @@ Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT
*/

if (size) *size = (UInt64)st.st_size;
if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime);
if (cTime)
{
const CFiTime ct = StoreOldestCTime ? FiTime_Min3(ST_CTIME(st), ST_ATIME(st), ST_MTIME(st)) : ST_CTIME(st);
FiTime_To_FILETIME(ct, *cTime);
}
if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime);
if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime);
if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/Common/FileStreams.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Z7_class_final(CInFileStream) :

bool _info_WasLoaded;
bool SupportHardLinks;
bool StoreOldestCTime;
IInFileStream_Callback *Callback;
UINT_PTR CallbackRef;

Expand Down
17 changes: 15 additions & 2 deletions CPP/7zip/UI/Common/ArchiveCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ enum Enum
kNameTrailReplace,

kDeleteAfterCompressing,
kSetArcMTime
kSetArcMTime,
kOldestCTime

#ifndef Z7_NO_CRYPTO
, kPassword
Expand Down Expand Up @@ -356,7 +357,8 @@ static const CSwitchForm kSwitchForms[] =
{ "snt", SWFRM_MINUS },

{ "sdel", SWFRM_SIMPLE },
{ "stl", SWFRM_SIMPLE }
{ "stl", SWFRM_SIMPLE },
{ "stc", SWFRM_SIMPLE }

#ifndef Z7_NO_CRYPTO
, { "p", SWFRM_STRING }
Expand Down Expand Up @@ -1538,6 +1540,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
nt.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs)
nt.OpenShareForWrite = true;
if (parser[NKey::kOldestCTime].ThereIs)
nt.OldestCTime = true;
}

if (parser[NKey::kZoneFile].ThereIs)
Expand Down Expand Up @@ -1699,6 +1703,15 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs;
updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs;

if (parser[NKey::kOldestCTime].ThereIs)
{
updateOptions.StoreOldestCTime = true;
// force storing CTime into archive (same as "-mtc"):
CProperty prop;
prop.Name = L"tc";
updateOptions.MethodMode.Properties.Add(prop);
}

if (updateOptions.StdOutMode && updateOptions.EMailMode)
throw CArcCmdLineException("stdout mode and email mode cannot be combined");

Expand Down
25 changes: 21 additions & 4 deletions CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ void CArchiveExtractCallback::CorrectPathParts()
}


static void GetFiTimesCAM(const CProcessedFileInfo &fi, CFiTimesCAM &pt, const CArc &arc)
static void GetFiTimesCAM(const CProcessedFileInfo &fi, CFiTimesCAM &pt, const CArc &arc, bool oldestCTime)
{
pt.CTime_Defined = false;
pt.ATime_Defined = false;
Expand Down Expand Up @@ -1092,6 +1092,23 @@ static void GetFiTimesCAM(const CProcessedFileInfo &fi, CFiTimesCAM &pt, const C
fi.ATime.Write_To_FiTime(pt.ATime);
pt.ATime_Defined = true;
}

if (oldestCTime)
{
// the oldest of the defined times becomes the creation time
const CFiTime *oldest = NULL;
if (pt.CTime_Defined)
oldest = &pt.CTime;
if (pt.ATime_Defined && (!oldest || Compare_FiTime(&pt.ATime, oldest) < 0))
oldest = &pt.ATime;
if (pt.MTime_Defined && (!oldest || Compare_FiTime(&pt.MTime, oldest) < 0))
oldest = &pt.MTime;
if (oldest)
{
pt.CTime = *oldest;
pt.CTime_Defined = true;
}
}
}


Expand Down Expand Up @@ -1163,7 +1180,7 @@ void CArchiveExtractCallback::CreateFolders()
return;

CDirPathTime pt;
GetFiTimesCAM(_fi, pt, *_arc);
GetFiTimesCAM(_fi, pt, *_arc, _ntOptions.OldestCTime);

if (pt.IsSomeTimeDefined())
{
Expand Down Expand Up @@ -1972,7 +1989,7 @@ HRESULT CArchiveExtractCallback::CloseFile()
#endif

CFiTimesCAM t;
GetFiTimesCAM(_fi, t, *_arc);
GetFiTimesCAM(_fi, t, *_arc, _ntOptions.OldestCTime);

// #ifdef _WIN32
if (t.IsSomeTimeDefined())
Expand Down Expand Up @@ -2987,7 +3004,7 @@ HRESULT CArchiveExtractCallback::SetPostLinks() const
#endif

CFiTimesCAM pt;
GetFiTimesCAM(link.item_FileInfo, pt, *_arc);
GetFiTimesCAM(link.item_FileInfo, pt, *_arc, _ntOptions.OldestCTime);
if (pt.IsSomeTimeDefined())
pt.SetLinkFileTime_to_FS(link.fullProcessedPath_from);

Expand Down
2 changes: 2 additions & 0 deletions CPP/7zip/UI/Common/ArchiveExtractCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct CExtractNtOptions
// used for hash arcs only, when we open external files
bool PreserveATime;
bool OpenShareForWrite;
bool OldestCTime;

unsigned SymLinks_DangerousLevel;

Expand All @@ -75,6 +76,7 @@ struct CExtractNtOptions
ExtractOwner(false),
PreserveATime(false),
OpenShareForWrite(false),
OldestCTime(false),
SymLinks_DangerousLevel(5),
MemLimit((UInt64)(Int64)-1)
{
Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/UI/Common/Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ static HRESULT Compress(
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);

updateCallbackSpec->PreserveATime = options.PreserveATime;
updateCallbackSpec->StoreOldestCTime = options.StoreOldestCTime;
updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError;
updateCallbackSpec->StdInMode = options.StdInMode;
Expand Down
2 changes: 2 additions & 0 deletions CPP/7zip/UI/Common/Update.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct CUpdateOptions

bool DeleteAfterCompressing;
bool SetArcMTime;
bool StoreOldestCTime;
bool RenameMode;

CBoolPair NtSecurity;
Expand Down Expand Up @@ -140,6 +141,7 @@ struct CUpdateOptions

DeleteAfterCompressing(false),
SetArcMTime(false),
StoreOldestCTime(false),
RenameMode(false),

ArcNameMode(k_ArcNameMode_Smart),
Expand Down
6 changes: 4 additions & 2 deletions CPP/7zip/UI/Common/UpdateCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ bool InitLocalPrivileges();

CArchiveUpdateCallback::CArchiveUpdateCallback():
PreserveATime(false),
StoreOldestCTime(false),
ShareForWrite(false),
StopAfterOpenError(false),
StdInMode(false),
Expand Down Expand Up @@ -167,7 +168,7 @@ Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *val
{
case kpidIsDir: prop = true; break;
case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->GetWinAttrib(); break;
case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->CTime); break;
case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, StoreOldestCTime ? FiTime_Min3(ParentDirItem->CTime, ParentDirItem->ATime, ParentDirItem->MTime) : ParentDirItem->CTime); break;
case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break;
case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break;
case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break;
Expand Down Expand Up @@ -514,7 +515,7 @@ Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = (UInt64)(di.IsDir() ? (UInt64)0 : di.Size); break;
case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break;
case kpidCTime: PropVariant_SetFrom_FiTime(prop, StoreOldestCTime ? FiTime_Min3(di.CTime, di.ATime, di.MTime) : di.CTime); break;
case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break;
case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break;
case kpidAttrib: /* if (di.Attrib_IsDefined) */ prop = (UInt32)di.GetWinAttrib(); break;
Expand Down Expand Up @@ -697,6 +698,7 @@ Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
#endif

inStreamSpec->SupportHardLinks = StoreHardLinks;
inStreamSpec->StoreOldestCTime = StoreOldestCTime;
const bool preserveATime = (PreserveATime
|| mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass.
inStreamSpec->Set_PreserveATime(preserveATime);
Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/UI/Common/UpdateCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class CArchiveUpdateCallback Z7_final:

public:
bool PreserveATime;
bool StoreOldestCTime;
bool ShareForWrite;
bool StopAfterOpenError;
bool StdInMode;
Expand Down
3 changes: 3 additions & 0 deletions CPP/7zip/UI/Common/ZipRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ static LPCTSTR const kAltStreams = TEXT("AltStreams");
static LPCTSTR const kHardLinks = TEXT("HardLinks");
static LPCTSTR const kSymLinks = TEXT("SymLinks");
static LPCTSTR const kPreserveATime = TEXT("PreserveATime");
static LPCTSTR const kOldestCTime = TEXT("OldestCTime");

static LPCTSTR const kTimePrec = TEXT("TimePrec");
static LPCTSTR const kMTime = TEXT("MTime");
Expand Down Expand Up @@ -264,6 +265,7 @@ void CInfo::Save() const
Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks);
Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks);
Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime);
Key_Set_BoolPair_Delete_IfNotDef (key, kOldestCTime, OldestCTime);

key.SetValue(kShowPassword, ShowPassword);
key.SetValue(kLevel, (UInt32)Level);
Expand Down Expand Up @@ -325,6 +327,7 @@ void CInfo::Load()
Key_Get_BoolPair(key, kHardLinks, HardLinks);
Key_Get_BoolPair(key, kSymLinks, SymLinks);
Key_Get_BoolPair(key, kPreserveATime, PreserveATime);
Key_Get_BoolPair(key, kOldestCTime, OldestCTime);

key.GetValue_Strings(kArcHistory, ArcPaths);

Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/UI/Common/ZipRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ namespace NCompression
CBoolPair SymLinks;

CBoolPair PreserveATime;
CBoolPair OldestCTime;

UString ArcType;
UStringVector ArcPaths;
Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/UI/Console/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static const char * const kHelpString =
" -sse : stop archive creating, if it can't open some input file\n"
" -ssp : do not change Last Access Time of source files while archiving\n"
" -ssw : compress shared files\n"
" -stc : set creation time to oldest of access/modification/creation time\n"
" -stl : set archive timestamp from the most recently modified file\n"
" -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n"
" -stx{Type} : exclude archive type\n"
Expand Down
8 changes: 7 additions & 1 deletion CPP/7zip/UI/GUI/CompressDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,11 @@ void CCompressDialog::FormatChanged(bool isChanged)
SET_GUI_BOOL (AltStreams);
SET_GUI_BOOL (NtSecurity);
SET_GUI_BOOL (PreserveATime);
SET_GUI_BOOL (OldestCTime);
}

PreserveATime.Supported = true;
OldestCTime.Supported = true;

{
const CArcInfoEx &ai = Get_ArcInfoEx();
Expand Down Expand Up @@ -1194,6 +1196,7 @@ void CCompressDialog::OnOK()
SET_FINAL_BOOL_PAIRS (NtSecurity);

SET_FINAL_BOOL_PAIRS (PreserveATime);
SET_FINAL_BOOL_PAIRS (OldestCTime);
}

{
Expand Down Expand Up @@ -3690,7 +3693,8 @@ static const UInt32 kLangIDs_Options[] =
IDX_COMPRESS_CTIME,
IDX_COMPRESS_ATIME,
IDX_COMPRESS_ZTIME,
IDX_COMPRESS_PRESERVE_ATIME
IDX_COMPRESS_PRESERVE_ATIME,
IDX_COMPRESS_OLDEST_CTIME
};
#endif

Expand Down Expand Up @@ -3737,6 +3741,7 @@ bool COptionsDialog::OnInit()
CheckButton_Bool1 ( IDX_COMPRESS_NT_SECUR, cd->NtSecurity);

CheckButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
CheckButton_Bool1 (IDX_COMPRESS_OLDEST_CTIME, cd->OldestCTime);

m_Prec.Attach (GetItem(IDC_COMPRESS_TIME_PREC));

Expand Down Expand Up @@ -3801,6 +3806,7 @@ void COptionsDialog::OnOK()
GetButton_Bool1 (IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams);
GetButton_Bool1 (IDX_COMPRESS_NT_SECUR, cd->NtSecurity);
GetButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
GetButton_Bool1 (IDX_COMPRESS_OLDEST_CTIME, cd->OldestCTime);

Store_TimeBoxes();
{
Expand Down
4 changes: 3 additions & 1 deletion CPP/7zip/UI/GUI/CompressDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace NCompressDialog
CBoolPair NtSecurity;

CBoolPair PreserveATime;
CBoolPair OldestCTime;

UInt32 TimePrec;
CBoolPair MTime;
Expand Down Expand Up @@ -147,6 +148,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
CBool1 AltStreams;
CBool1 NtSecurity;
CBool1 PreserveATime;
CBool1 OldestCTime;
private:
bool _ramSize_Defined;

Expand Down Expand Up @@ -468,7 +470,7 @@ class COptionsDialog: public NWindows::NControl::CModalDialog

INT_PTR Create(HWND wndParent = NULL)
{
BIG_DIALOG_SIZE(240, 232);
BIG_DIALOG_SIZE(240, 252);
return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS_OPTIONS), wndParent);
}

Expand Down
1 change: 1 addition & 0 deletions CPP/7zip/UI/GUI/CompressDialogRes.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
#define IDX_COMPRESS_ATIME 4084
#define IDX_COMPRESS_ZTIME 4085
#define IDX_COMPRESS_PRESERVE_ATIME 4086
#define IDX_COMPRESS_OLDEST_CTIME 4087

#define IDS_COMPRESS_SEC 4090
#define IDS_COMPRESS_NS 4091
Expand Down
9 changes: 7 additions & 2 deletions CPP/7zip/UI/GUI/CompressOptionsDialog.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"

#define xc 240
#define yc 232
#define yc 252

#define g5x m
#define g5x2 (g5x + m)
Expand Down Expand Up @@ -35,7 +35,7 @@ BEGIN
LTEXT "", IDT_COMPRESS_TIME_INFO, g5x, timePosY - 14, g5xs, 8


GROUPBOX "Time", IDG_COMPRESS_TIME, g5x, timePosY, g5xs, 112
GROUPBOX "Time", IDG_COMPRESS_TIME, g5x, timePosY, g5xs, 132

// MY_CONTROL_CHECKBOX ("Default", IDX_COMPRESS_TIME_DEFAULT,
// ntPosX, timePosY + 10, ntSizeX)
Expand Down Expand Up @@ -71,6 +71,11 @@ BEGIN
"Do not change source files last access time",
IDX_COMPRESS_PRESERVE_ATIME,
ntPosX, timePosY + 92, ntSizeX)

MY_CONTROL_CHECKBOX_2LINES(
"Set creation time to oldest of access/modification/creation time",
IDX_COMPRESS_OLDEST_CTIME,
ntPosX, timePosY + 112, ntSizeX)


DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP
Expand Down
Loading