/****************************** Module Header ******************************* * * Module Name: backup.e * * Copyright (c) Netlabs EPM Distribution Project 2008 * * $Id$ * * =========================================================================== * * This file is part of the Netlabs EPM Distribution package and is free * software. You can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * Netlabs EPM Distribution. This library is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * ****************************************************************************/ compile if not defined( SMALL) -- If compiled separately EA_comment 'This defines macros for backup and autosave operations.' define INCLUDING_FILE = 'BACKUP.E' include 'stdconst.e' const tryinclude 'mycnf.e' const compile if not defined( NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' compile endif ; --------------------------------------------------------------------------- defc AutoSave universal vdefault_autosave universal ring_enabled uparg = upcase( arg( 1)) if uparg = ON__MSG then .autosave = vdefault_autosave elseif uparg = OFF__MSG then .autosave = 0 elseif IsNum( uparg) then .autosave = uparg elseif uparg = 'DIR' then 'ListBackupDir' elseif uparg = '' then 'CommandLine AutoSave' .autosave elseif uparg = '?' then if ring_enabled then -- For campatibility: if 6 = WinMessageBox( AUTOSAVE__MSG, CURRENT_AUTOSAVE__MSG || .autosave\10 || NAME_IS__MSG || MakeBakName()\10\10 || LIST_DIR__MSG, 16436) -- YESNO + MB_INFORMATION + MOVEABLE then 'Dir' GetBackupDir() endif else call WinMessageBox( AUTOSAVE__MSG, CURRENT_AUTOSAVE__MSG || .autosave\10 || NAME_IS__MSG || MakeBakName()\10\10 || NO_LIST_DIR__MSG, 16432) -- OK + MB_INFORMATION + MOVEABLE endif -- ring_enabled return else 'SayError 'AUTOSAVE_PROMPT__MSG'.' return endif -- uparg = ON__MSG 'SayError 'CURRENT_AUTOSAVE__MSG || .autosave', 'NAME_IS__MSG || MakeBakName()'.' ; --------------------------------------------------------------------------- defc DeleteAutoSaveFile if .autosave then -- Erase the tempfile if autosave is on. --TempName = MakeTempName() TempName = MakeBakName() getfileid tempid, TempName -- (provided it's not in the ring.) if tempid = '' then call EraseTemp( TempName) endif endif ; --------------------------------------------------------------------------- ; arg( 1) = number. Opens dialog if no arg. defc AutosaveNum KeyPath = '\NEPMD\User\AutoSave\Number' Num = QueryConfigKey( KeyPath, 0) CurNum = Num NewNum = strip( arg( 1)) if NewNum = '' then if Num = '' then Num = 100 endif Title = 'Autosave number' Text = 'Number of modifications before file is saved:' Text = Text''copies( ' ', Max( 0, 100 - length( Text))) Entry = Num parse value EntryBox( Title, '', Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with button 2 NewNum \0 NewNum = strip( NewNum) if button <> \1 then return endif endif if NewNum <> CurNum then if IsNum( NewNum) then WriteConfigKey( KeyPath, NewNum) if isadefproc( 'MenuText_autosavenumdialog') then MenuText_autosavenumdialog() endif -- Set new .autosave value for all files getfileid startfid -- Loop through all files in ring 'VSyncCursor' do f = 1 to filesinring( 1) -- Provide an upper limit; prevent looping forever if IsABackupFile() then .autosave = NewNum endif nextfile getfileid fid if fid = startfid then leave endif enddo else 'SayError Autosave number not changed.' 'PostMe AutosaveNum' endif endif ; --------------------------------------------------------------------------- ; arg( 1) = number. Opens dialog if no arg. defc BackupNum KeyPath = '\NEPMD\User\Backup\Number' Num = QueryConfigKey( KeyPath, 0) CurNum = Num NewNum = strip( arg( 1)) if NewNum = '' then if Num = '' then Num = 10 endif Title = 'Backup number' Text = 'Number of kept backup files:' Text = Text''copies( ' ', Max( 0, 100 - length( Text))) Entry = Num parse value EntryBox( Title, '', Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with button 2 NewNum \0 NewNum = strip( NewNum) if button <> \1 then return endif endif if NewNum <> CurNum then if IsNum( NewNum) then call WriteConfigKey( KeyPath, NewNum) if isadefproc( 'MenuText_backupnumdialog') then MenuText_backupnumdialog() endif else 'SayError Backup number not changed.' 'PostMe BackupNum' endif endif ; --------------------------------------------------------------------------- ; arg( 1) = Directory. Opens dialog if no arg. defc BackupDir Dir = GetBackupDir() DefaultDir = GetDefaultBackupDir() NewDir = strip( arg( 1)) if NewDir = '' then Title = 'Backup directory' Text = 'Enter a fully-qualified or relative directory. Use = for the file''s directory:' Text = Text''copies( ' ', Max( 0, 100 - length( Text))) Buttons = '/~Set/~Reset/'CANCEL__MSG Entry = Dir if rightstr( Entry, 2) <> ':\' then Entry = strip( Entry, 'T', '\') endif parse value EntryBox( Title, Buttons, Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with button 2 NewDir \0 NewDir = strip( NewDir) if button = \1 then -- Set -- nop elseif button = \2 then -- Reset NewDir = '' else -- Cancel return endif endif call SetBackupDir( NewDir) ; --------------------------------------------------------------------------- defc ListBackupDir Dir = GetBackupDir() if Dir = '=' then if leftstr( .filename, 1) = '.' then Dir = directory() else lp = lastpos( '\', .filename) Dir = leftstr( .filename, lp - 1) if substr( Dir, 2, 1) = ':' then Dir = Dir'\' endif endif endif FileSpec = Dir SortOrder = '/F N' -- = default order 'TreeDir' EnquoteFileSpec( FileSpec) SortOrder if not rc then .filename = '.TreeBackup' EnquoteFileSpec( FileSpec) SortOrder endif ; --------------------------------------------------------------------------- defc ListBackupDirCurrentFile lp = lastpos( '\', .filename) Name = substr( .filename, lp + 1) Dir = GetBackupDir() if Dir = '=' then if leftstr( .filename, 1) = '.' then Dir = directory() else Dir = leftstr( .filename, lp - 1) if substr( Dir, 2, 1) = ':' then Dir = Dir'\' endif endif endif FileSpec = strip( Dir, 'T', '\')'\'Name'~*' Handle = '' NextFilename = '' -- Check if backups for Name exist fFound = 0 if NepmdGetNextFile( FileSpec, Handle, NextFilename) then NepmdGetNextClose( Handle) fFound = 1 -- TreeBackup 'TreeBackup' EnquoteFileSpec( FileSpec) else Untitled = GetUnnamedFilename() FileSpec = strip( Dir, 'T', '\')'\'Untitled'~*' Handle = '' NextFilename = '' -- Check if backups for .Untitled exist if NepmdGetNextFile( FileSpec, Handle, NextFilename) then NepmdGetNextClose( Handle) fFound = 1 endif if fFound then -- Query to open backups for .Untitled instead. Title = 'TreeBackup 'Name Text = '' Text = Text || 'No backup file found for 'Name'.'\n\n Text = Text || 'List backups for 'Untitled' instead?'\n\n Style = MB_OKCANCEL + MB_ICONQUESTION + MB_MOVEABLE rcx = WinMessageBox( Title, Text, Style) if rcx = MBID_OK then -- TreeBackup 'TreeBackup' EnquoteFileSpec( FileSpec) endif else 'SayError No backup file found for 'Name'.' endif endif ; --------------------------------------------------------------------------- defc TreeBackup -- Strip appended SortOption ParseTreeTitleFilename( strip( arg( 1)), Filename, SortOption) DefaultFileSortOption = '/R D' DefaultDirSortOption = '/F N' if SortOption = '' then if NepmdDirExists( Filename) then SortOption = DefaultDirSortOption else SortOption = DefaultFileSortOption endif endif 'TreeDir' EnquoteFileSpec( Filename) SortOption treedirrc = rc Displayname = '.TreeBackup' EnquoteFileSpec( Filename) SortOption if not treedirrc then .filename = Displayname 'TreeSort' SortOption -- TreeDir executes already QuitSameFile, but before renaming it --'PostMe QuitSameFile' -- TreeDir already does this else -- Temp. file is already quit by TreeCommonFinish. endif ; --------------------------------------------------------------------------- defproc IsABackupFile Filename = arg( 1) if Filename = '' then Filename = .filename endif getfileid fid, Filename -- Skip temp. files according to config if FileShouldBeDiscarded( Filename) then fCreateBackup = 0 else fCreateBackup = 1 endif return fCreateBackup defc IsABackupFile Filename = StripQuotesFileSpec( strip( arg( 1))) if Filename = '' then Filename = .filename endif 'SayError 'Filename': fCreateBackup =' IsABackupFile()'.' ; --------------------------------------------------------------------------- ; Procedure to pick a filename for backup purposes, like STDPROCS.E~. defproc MakeBakName FullName = arg( 1) if FullName = '' then FullName = .filename endif BackupDir = GetBackupDir() -- Get backup dir if leftstr( BackupDir, 1) = '=' then if length( BackupDir > 1) then BackupDirRest = strip( substr( BackupDir, 2), 'L', '\') else BackupDirRest = '' endif lp = lastpos( '\', FullName) if BackupDirRest <> '' then BackupDir = leftstr( FullName, lp - 1)'\'BackupDirRest else BackupDir = leftstr( FullName, lp - 1) endif elseif substr( BackupDir, 2, 1) <> ':' then -- a relative name lp = lastpos( '\', FullName) BackupDir = leftstr( FullName, lp - 1)'\'BackupDir endif -- Maybe create backup tree BackupDir = strip( BackupDir, 'T', '\') fCreateDir = 1 if rightstr( BackupDir, 1) = ':' then fCreateDir = 0 elseif leftstr( BackupDir, 2) = '\\' then parse value BackupDir'\' with '\\' MachineName '\' Resource '\' SubDir if SubDir = '' then fCreateDir = 0 endif endif if fCreateDir then if not NepmdDirExists( BackupDir) then call MakeTree( BackupDir) endif endif -- Get file sys FileSys = '' if substr( BackupDir, 1, 2) = '\\' then FileSys = 'LAN' -- Assume it's not FAT elseif substr( BackupDir, 2, 1) = ':' then FileSys = QueryFileSys( leftstr( BackupDir, 2)) elseif substr( FullName, 2, 1) = ':' then FileSys = QueryFileSys( leftstr( FullName, 2)) endif -- Strip path lp = lastpos( '\', translate( FullName, '\', '/')) if lp > 0 then Name = substr( FullName, lp + 1) else Name = FullName endif -- Handle FAT names if FileSys = 'FAT' | FileSys = '' then Name = ConvertToFatName( Name) endif -- Parse Name into base and ext extp = lastpos( '.', Name) if extp > 1 then base = leftstr( Name, extp - 1) ext = substr( Name, extp + 1) -- extension without '.' else base = Name ext = '' endif -- Append backup postfix to ext if FileSys = 'FAT' | FileSys = '' then if length( ext) > 1 then ext = substr( ext, 1, 1)'~' else ext = ext'~' endif elseif ext = '' then base = base'~' else ext = ext'~' endif ; -- We still use MakeTempName() for its handling of host names. ; bakname = MakeTempName( Name) ; i = lastpos( '\', bakname) -- but with a different directory ; if i then ; bakname = substr( bakname, i + 1) ; endif ; parse value bakname with base'.'. -- Prepend backup dir if ext = '' then NewName = base else NewName = base'.'ext endif BackupName = BackupDir'\'NewName return BackupName ; --------------------------------------------------------------------------- ; Renames File~(n - 1) to File~n, ..., File~0 to File~1 ; and then copies File to File~0. defproc MakeBackup rc = 0 Filename = arg( 1) if Filename = '' then Filename = .filename getfileid fid else getfileid fid, Filename endif do once = 1 to 1 lp = lastpos( '\', translate( Filename, '\', '/')) fHasDir = 0 if lp > 0 then fHasDir = 1 endif KeyPath = '\NEPMD\User\Backup' fBackupEnabled = QueryConfigKey( KeyPath, 0) if not fBackupEnabled then leave endif -- Avoid backup of files that are not in the ring if fid = '' then leave endif -- Avoid backup of empty or almost empty (e.g. CRLF only) files Size = NepmdQueryPathInfo( Filename, 'SIZE') if rc then rc = 0 leave endif if Size <= 2 then leave elseif fid.last < 1 then leave elseif fid.last = 1 then if strip( textline( fid.last)) = '' then leave endif endif -- Bypass the following checks if fForce is specified fForce = (arg( 2) == 1) if not fForce then -- Avoid backup if file should be discarded if not IsABackupFile( Filename) then leave endif -- Avoid backup of unmodified files if fid.modify = 0 then leave endif endif BackupName = MakeBakName( Filename) lp = lastpos( '\', Filename) FilePath = leftstr( Filename, Max( 0, lp - 1)) BackupNum = GetBackupNum() Maxn = BackupNum - 1 -- Query all file dates in advance, not during overwriting files do n = 0 to (BackupNum - 1) rc = 0 FiledateHex = GetFileDateHex( BackupName''n) if rc = 0 then SetAVar( 'File.'n'.IsoDate', FileDateHexToIsoDate( FileDateHex)) else SetAVar( 'File.'n'.IsoDate', 0) -- File doesn't exist endif enddo -- Keep BackupNum backups. -- Don't overwrite too new files to keep at least a few older ones. -- o With the date checks below and BackupNum = 10, the files -- filename~0 ... filename~4 are not checked for their dates. -- o filename~5 ... filename~7 are only overwritten with newer files, -- if newer files are at least 1 h newer. -- o filename~8 ... filename~9 are only overwritten with newer files, -- if newer files are at least 24 h newer. -- Determine Maxn by date comparison do n = 1 to (BackupNum - 1) m = n - 1 rc = 0 NewFile = BackupName''m if GetAVar( 'File.'m'.IsoDate') = 0 then -- NewFile doesn't exist iterate -- MoveFile not possible endif FileDateNew = GetAVar( 'File.'m'.IsoDate') OldFile = BackupName''n if GetAVar( 'File.'n'.IsoDate') = 0 then -- OldFile doesn't exist -- nop else FileDateOld = GetAVar( 'File.'n'.IsoDate') DiffDateDays = DateTimeDiff( FileDateOld, FileDateNew, 'd') DiffDateMins = 24 * 60 * DiffDateDays -- Using the max. of 10 and BackupNum instead of BackupNum -- effects BackupNum > 10 only. Then only the per-day amount -- increases, not the other parts. CalcNum = Max( 10, BackupNum) if n >= CalcNum - CalcNum % 4 then -- Example: 10 - 10 % 4 = 8, check for 7 -> 8 and above if DiffDateMins < 60 * 24 then -- 60 * 24 min = 24 h Maxn = Min( Maxn, n - 1) -- OldFile too new, don't overwrite endif elseif n >= CalcNum % 2 then -- Example: 10 % 2 = 5, check for 4 -> 5 and above if DiffDateMins < 60 then -- 60 min = 1 h Maxn = Min( Maxn, n - 1) -- OldFile too new, don't overwrite endif endif endif enddo -- Move newer file~m to older file~n do n = (BackupNum - 1) to 1 by -1 m = n - 1 rc = 0 if n > Maxn then iterate endif if GetAVar( 'File.'m'.IsoDate') = 0 then -- NewFile doesn't exist iterate -- MoveFile not possible endif -- Overwrites without asking, works also if destination file -- doesn't exist. call MoveFile( BackupName''m, BackupName''n) enddo -- Create the most recent backup if fHasDir then if Exist( Filename) then -- Filename must exist for Dos32Copy call CopyFile( Filename, BackupName''0) else -- For non-existing temp. files, xcom s must be used. 'xcom Save' BackupName''0 endif else -- Check if autosave file exists (BackupName = name~) if Exist( BackupName) then -- Filename must exist for Dos32Copy call CopyFile( BackupName, BackupName''0) else -- For non-existing temp. files, xcom s must be used. 'xcom Save' BackupName''0 endif endif -- Write EPM.PREVPATH EA call NepmdWriteStringEa( BackupName''0, 'EPM.PREVPATH', FilePath) -- Write EPM.BACKUPDATETIME EA call NepmdWriteStringEa( BackupName''0, 'EPM.BACKUPDATETIME', DateTime()) --dprintf( 'MakeBackup: rc = 'rc', BackupName = 'BackupName', BackupNum = 'BackupNum) enddo return ; --------------------------------------------------------------------------- defproc GetBackupOrgFilename( BackupFilename) OrgName = arg( 2) if OrgName = '' then Filename = BackupFilename -- Split tilde and number or 'org' do once = 1 to 1 lp = lastpos( '~', BackupFilename) if lp = 0 then leave endif Num = substr( BackupFilename, lp + 1) if not IsNum( Num) & not upcase( Num) = 'ORG' then leave endif Filename = leftstr( BackupFilename, lp - 1) enddo -- Split path lp = lastpos( '\', Filename) OrgName = substr( Filename, lp + 1) endif OrgFilename = '' if OrgFilename = '' then -- Get OrgFilename from EA PrevPath = NepmdQueryStringEa( BackupFilename, 'EPM.PREVPATH') if PrevPath <> '' then next = strip( PrevPath, 't', '\')'\'OrgName if Exist( next) then OrgFilename = next endif endif endif if OrgFilename = '' then -- Find OrgFile in ring getfileid startfid -- Go to .TreeBackup ... file for current file Dir = GetBackupDir() TreeDirFilename = '.TreeBackup' strip( Dir, 'T', '\')'\'OrgName'~*' getfileid TreeDirFid, TreeDirFilename if TreeDirFid <> '' then activatefile TreeDirFid endif -- Start at previous file - this may be OrgFile prevfile getfileid firstfid 'VSyncCursor' do f = 1 to filesinring( 1) getfileid fid lp = lastpos( '\', .filename) ThisName = substr( .filename, lp + 1) if ThisName = OrgName then OrgFilename = .filename leave endif nextfile if fid = firstfid then leave endif enddo activatefile startfid endif return OrgFilename ; --------------------------------------------------------------------------- defc CompareBackupFile BackupFilename = GetTreeListFilename() OrgFilename = GetBackupOrgFilename( BackupFilename) 'CompareFiles' EnquoteFilespec( OrgFilename) EnquoteFilespec( BackupFilename) ; --------------------------------------------------------------------------- defc RestoreFromTreeFile 'Restore' EnquoteFilespec( GetTreeListFilename()) ; --------------------------------------------------------------------------- defc Restore BackupFilename = StripQuotesFileSpec( strip( arg( 1))) if BackupFilename = '' then 'SayError Missing argument: BackupFilename.' return endif lp = lastpos( '\', BackupFilename) BackupPath = leftstr( BackupFilename, Max( 0, lp - 1)) if rightstr( BackupPath, 1) = ':' then BackupPath = BackupPath'\' endif BackupName = substr( BackupFilename, lp + 1) OrgFilename = GetBackupOrgFilename( BackupFilename) DefaultOrgFilename = OrgFilename -- Split path lp = lastpos( '\', OrgFilename) OrgName = substr( OrgFilename, lp + 1) Title = 'Restore 'OrgName Text = 'Copy backup file 'BackupName' over:' Text = Text''copies( ' ', Max( 0, 100 - length( Text))) Entry = DefaultOrgFilename parse value EntryBox( Title, '', Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with button 2 OrgFilename \0 if button = \1 & OrgFilename <> '' then do once = 1 to 1 -- Create a copy of the original file SaveOrgFilename = strip( BackupPath, 'T', '\')'\'OrgName'~org' -- Use a .tmp file for the backup file, if required fDeleteBackupFile = 0 if upcase( SaveOrgFilename) = upcase( BackupFilename) then BackupFilename = BackupFilename'.tmp' call CopyFile( SaveOrgFilename, BackupFilename) if not rc then fDeleteBackupFile = 1 endif endif fOrgBackupCreated = 0 call CopyFile( OrgFilename, SaveOrgFilename) if not rc then fOrgBackupCreated = 1 -- Remove .LONGNAME EA to make the new name visible call NepmdDeleteStringEa( SaveOrgFilename, '.LONGNAME') lp = lastpos( '\', OrgFilename) FilePath = leftstr( OrgFilename, Max( 0, lp - 1)) -- Write EPM.PREVPATH EA call NepmdWriteStringEa( SaveOrgFilename, 'EPM.PREVPATH', FilePath) -- Write EPM.BACKUPDATETIME EA call NepmdWriteStringEa( SaveOrgFilename, 'EPM.BACKUPDATETIME', DateTime()) endif -- Copy backup file call CopyFile( BackupFilename, OrgFilename) if rc then leave endif -- Delete .tmp file, if created above if fDeleteBackupFile then call EraseTemp( BackupFilename) endif -- Remove backup EAs call NepmdDeleteStringEa( OrgFilename, 'EPM.PREVPATH') call NepmdDeleteStringEa( OrgFilename, 'EPM.BACKUPDATETIME') Msg = 'File restored: 'OrgFilename if fOrgBackupCreated then Msg = Msg', previous file saved as: 'SaveOrgFilename endif 'SayError' Msg -- Revert getfileid OrgFid, OrgFilename if OrgFid = '' then leave endif activatefile OrgFid 'Revert' enddo endif ; --------------------------------------------------------------------------- ; Saves current buffer to File~. defproc MakeAutoSave rc = 0 Filename = .filename KeyPath = '\NEPMD\User\AutoSave' fAutoSaveEnabled = QueryConfigKey( KeyPath, 0) if not fAutoSaveEnabled then return endif if not IsABackupFile( Filename) then return endif AutoSaveName = MakeBakName( Filename) -- No 'Autosaving...' msg to avoid overriding of other msgs 'postme xcom s' AutoSaveName -- The autosave file will be removed on close or delete. -- Additionally, autosave always saves as the same filename. -- Usually backup is made only on save. -- For .Untitled and .command_shell_ files, a backup is created here as -- well on autosave. if Filename = GetUnnamedFileName() | IsAShellFilename( Filename) then call MakeBackup() backuprc = rc --dprintf( 'Autosave: Backup created for temp. file "'Filename'", rc = 'backuprc'.') endif -- Reraise the modify flag. .modify = 1 -- Using 1 here doesn't trigger a new modify event -- No deletion of 'Autosaving...' msg to avoid overriding of other msgs return ; --------------------------------------------------------------------------- defproc GetAutoSaveNum KeyPath = '\NEPMD\User\AutoSave\Number' AutoSaveNum = QueryConfigKey( KeyPath, 0) return AutoSaveNum ; --------------------------------------------------------------------------- defproc GetBackupNum KeyPath = '\NEPMD\User\Backup\Number' BackupNum = QueryConfigKey( KeyPath, 0) return BackupNum ; --------------------------------------------------------------------------- defproc GetBackupDir KeyPath = '\NEPMD\User\Backup\Directory' BackupDir = QueryConfigKey( KeyPath) BackupDir = ExpandEnvVars( BackupDir) if BackupDir = '' then BackupDir = GetDefaultBackupDir() endif return BackupDir ; --------------------------------------------------------------------------- defproc GetDefaultBackupDir DefaultBackupDir = GetTmpPath()'nepmd\backup' DefaultBackupDir = ExpandEnvVars( DefaultBackupDir) return DefaultBackupDir ; --------------------------------------------------------------------------- defproc SetBackupDir KeyPath = '\NEPMD\User\Backup\Directory' NewDir = arg( 1) if NewDir = '' then call DeleteConfigKey( KeyPath) else call WriteConfigKey( KeyPath, NewDir) endif if isadefproc( 'MenuText_backupdirdialog') then MenuText_backupdirdialog() endif ; --------------------------------------------------------------------------- ; This is exectued by ProcessPostMain when the last saved dateime is greater ; than the DiffDays period. DiffDays is defined in ProcessPostMain. ; The number of saved files in SaveDir is specified here. Older files are ; deleted. defc BackupIni BinDir = Get_Env( 'NEPMD_USERDIR')'\bin' SaveDir = GetBackupDir()'\ini' call MakeTree( SaveDir) NepmdIni = BinDir'\NEPMD.INI' SaveIni = SaveDir'\NEPMD_'word( DateTime(), 1)'.INI' MaxFiles = 10 TempFilename = '.backupini' -- Delete old files fid = LoadHiddenFile( TempFilename) FileMask = SaveDir'\NEPMD_*.INI' Handle = '' NextFilename = '' do while NepmdGetNextFile( FileMask, Handle, NextFilename) AppendHiddenFile( fid, NextFilename) --dprintf( NextFilename) enddo NumFound = fid.last - 1 -- First line is empty NumOld = Max( 0, NumFound - (MaxFiles - 1)) -- Keep MaxFiles - 1 --dprintf( 'NumFound = 'NumFound', NumOld = 'NumOld) do l = 2 to NumOld + 1 -- First line is empty getline OldIni, l, fid --dprintf( 'OldIni = 'OldIni) DeleteFile( OldIni) enddo CloseHiddenFile( fid) -- Create backup CopyFile( NepmdIni, SaveIni) -- Remove file attributes quietshell 'attrib -r -s -h' SaveIni -- Remove .LONGNAME EA to make the new name visible call NepmdDeleteStringEa( SaveIni, '.LONGNAME') -- Store last saved datetime KeyPath = '\NEPMD\Var\History\Ini\LastDateTime' call WriteConfigKey( KeyPath, DateTime()) ; --------------------------------------------------------------------------- defc DeleteOldBackupFiles universal vepm_pointer EaName = 'EPM.BACKUPDATETIME' KeyPath = '\NEPMD\User\Backup\MaxDays' MaxDays = QueryConfigKey( KeyPath) BackupDir = GetBackupDir() FileMask = BackupDir'\*' do forever -- Enter MaxDays Title = 'Select max. backup age in days' Text = 'Files saved before the specified days will be deleted:' Text = Text''copies( ' ', Max( 100 - length( Text), 0)) Buttons = '/~Set/'CANCEL__MSG Entry = MaxDays parse value EntryBox( Title, Buttons, Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with Button 2 NewMaxDays \0 NewMaxDays = strip( NewMaxDays) if Button = \1 then -- Set if not NewMaxDays then iterate elseif not IsNum( NewMaxDays) then iterate endif WriteConfigKey( KeyPath, NewMaxDays) MaxDays = NewMaxDays leave else -- Cancel return endif enddo -- i = 1: Count files, confirm, i = 2: delete, report do i = 1 to 2 Handle = '' NextFilename = '' NumFiles = 0 NumDelete = 0 mouse_setpointer WAIT_POINTER do while NepmdGetNextFile( FileMask, Handle, NextFilename) NumFiles = NumFiles + 1 BackupDateTime = NepmdQueryStringEa( NextFilename, EaName) fDelete = 0 if BackupDateTime then DiffDays = DateTimeDiff( BackupDateTime, '', 'd') if DiffDays > MaxDays then fDelete = 1 endif else fDelete = 1 endif if fDelete then if i = 1 then NumDelete = NumDelete + 1 elseif i = 2 then DeleteFile( NextFilename) NumDelete = NumDelete + 1 endif endif enddo mouse_setpointer vepm_pointer if i = 1 then Title = 'Delete old backup files' Text = '' Text = Text || NumDelete' files of 'NumFiles' selected for deletion.' Text = Text || ' These files were saved 'MaxDays' days ago and earlier.'\n\n Text = Text || 'Delete them now?' Style = MB_OKCANCEL + MB_QUERY + MB_DEFBUTTON1 + MB_MOVEABLE rcx = WinMessageBox( Title, Text, Style) if rcx = MBID_OK then if NumDelete = 0 then 'SayError DeleteOldBackupFiles: 'NumDelete' files of 'NumFiles' deleted.' leave else iterate endif else 'PostMe DeleteOldBackupFiles' -- Call this again leave endif elseif i = 2 then 'SayError DeleteOldBackupFiles: 'NumDelete' files of 'NumFiles' deleted.' endif enddo ; --------------------------------------------------------------------------- ; Unused. ; Procedure to pick a temporary filename like ORIGNAME.$$1. ; First argument is the filename, 2nd is the fileid. Both are optional, ; default to the current filename and fileid if absent. ; Revised by BTTUCKER to catch all cases and work with E3EMUL. defproc MakeTempName TempBase = arg( 1) TempExt = arg( 2) if TempBase = '' then -- if no arg given, default to current filename TempBase = .filename endif if TempBase = '' then TempBase = '$' -- new file? o.k. then $ else -- We want only PC file name, VM filename, or MVS firstname -- These next statements will strip everything else off... p = lastpos( '\', TempBase) -- PC filename with path if p then TempBase = substr( TempBase, p + 1) endif p = pos( '.', TempBase) -- PC or MVS filename if p then TempBase = substr( TempBase, 1, p - 1) endif p = pos( ' ', TempBase) -- VM filename (or HPFS) if p then TempBase = substr( TempBase, 1, p - 1) endif p = pos( ':', TempBase) -- VM or MVS filename if p then TempBase = substr( TempBase, p + 1) endif p = pos( "'", TempBase) -- MVS filename if p then TempBase = substr( TempBase, p + 1) endif if length( TempBase) > 8 then TempBase = substr( TempBase, 1, 8) -- HPFS names endif endif -- TempBase might still be blank, as for '.Untitled' file. if TempBase = '' then TempBase = '$' endif TempBase = strip( GetBackupDir(), 't', '\')'\'TempBase if TempExt = '' then -- default is current fileid getfileid TempExt endif -- In EPM we can have the same filename in multiple edit windows without -- knowing it, because different edit windows are actually separate -- instances of the editor. So try to make the tempname unique by -- combining the window handle with the fileid. Combine two middle -- digits of the window handle with the last digit of the fileid. TempExt = substr( getpminfo( EPMINFO_EDITCLIENT), 2, 2) || TempExt if length( TempExt) > 3 then -- could be > one digit, or something else TempExt = substr( TempExt, 2, 3) endif return TempBase'.'TempExt