This commit is contained in:
Michael H.G. Schmidt 2021-05-26 00:54:46 +02:00
commit e674d75a20
6 changed files with 780 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.exe
*.log
!snapcontrol.exe

20
LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2019-2021 Michael H.G. Schmidt
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

104
README.md Normal file
View File

@ -0,0 +1,104 @@
# Snapcontrol
Drive snapshot backup controller.
A backup wrapper program for Windows boxes.
- Starts a backup via Windows Scheduler using Drive Snapshot
- Asks the user for permission to start backup
- Different backup targets (LOCAL drive, SMB, FTP)
- Encryption support (via Drive Snapshot)
- Verifies the backup (optional)
- Full backup every month
- Daily differential backup
- Writes detailed logfile and history log
- Sends reports via email
This tool creates an image backups of windows machines, it uses the [Drive Snapshot](http://www.drivesnapshot.de/en/order.htm) tool by Tom Ehlert Software. Please support this great tool and buy a license.
It is a - so called - wrapper program.
This is a short description. Detailed documentation follows in the next days.
## USAGE
```dos
C:\>snapcontrol.exe /?
usage: snapcontrol.exe </I | /U | /D | /V>
/I = install program and config
/U = update scheduler job
/D = dry run
/V = show version
```
```dos
C:\>snapcontrol.exe /V
Version = V1.02
```
## Example run
```dos
[2021.05.25 (23:57:07)] ============== starting BACKUP ==============
[2021.05.25 (23:57:07)] snapcontrol.exe version = [ V1.02 ]
[2021.05.25 (23:57:07)] snapshot.exe version = [ V1.48 ]
[2021.05.25 (23:57:07)] OK. Running as Admin ...
[2021.05.25 (23:57:07)] INFO: using a NETWORK share for backup ...
[2021.05.25 (23:57:07)] INFO: found [ MARS_snapshot_05_ful_C.sna ]
[2021.05.25 (23:57:07)] INFO: found [ MARS_snapshot_05_ful_HD1-1.sna ]
[2021.05.25 (23:57:07)] INFO: Starting QUICKCHECK for [ MARS_snapshot_05_ful_C.sna ]
23:57:07 Start of Snapshot 1.48.18895 [May 6 2021] at 25.05.2021
23:57:07 Running on Windows 10 Professional 64-bit (19042)
23:57:07 Memory Info: Total: 7887Mb, Free: 4645Mb, Pagefile total: 9103Mb, Pagefile free: 5835Mb
23:57:07 Command line: c:\tools\snapshot64.exe --Logfile:c:\snapshot\backup.log --QuickCheck:\\bar\drive\image\MARS_snapshot_05_ful_C.sna
23:57:07 The file structure of \\bar\drive\image\MARS_snapshot_05_ful_C.sna is okay.
23:57:07 End of Snapshot 1.48 [May 6 2021] at 25.05.2021
[2021.05.25 (23:57:07)] INFO: Starting QUICKCHECK for [ MARS_snapshot_05_ful_HD1-1.sna ]
23:57:07 Start of Snapshot 1.48.18895 [May 6 2021] at 25.05.2021
23:57:07 Running on Windows 10 Professional 64-bit (19042)
23:57:07 Memory Info: Total: 7887Mb, Free: 4642Mb, Pagefile total: 9103Mb, Pagefile free: 5835Mb
23:57:07 Command line: c:\tools\snapshot64.exe --Logfile:c:\snapshot\backup.log --QuickCheck:\\bar\drive\image\MARS_snapshot_05_ful_HD1-1.sna
23:57:07 The file structure of \\bar\drive\image\MARS_snapshot_05_ful_HD1-1.sna is okay.
23:57:07 End of Snapshot 1.48 [May 6 2021] at 25.05.2021
[2021.05.25 (23:57:07)] INFO: executing command [ c:\tools\snapshot64.exe ]
[2021.05.25 (23:57:07)] DumpFile: [ \\bar\drive\image\MARS_snapshot_05_$type_$disk.sna ]
[2021.05.25 (23:57:07)] HashFile: [ -h\\bar\drive\image\MARS_snapshot_05_$type_$disk.hsh ]
[2021.05.25 (23:57:07)] LogFile: [ c:\snapshot\backup.log ]
23:57:08 Start of Snapshot 1.48.18895 [May 6 2021] at 25.05.2021
23:57:08 Running on Windows 10 Professional 64-bit (19042)
23:57:08 Memory Info: Total: 7887Mb, Free: 4641Mb, Pagefile total: 9103Mb, Pagefile free: 5836Mb
23:57:08 Command line: c:\tools\snapshot64.exe --Logfile:c:\snapshot\backup.log -T --EjectDriveAfterBackup --NetUse:\\bar\drive\image,guest,******************** --FullIfHashIsMissing --CreateDir -W -L65536 HD1:* \\bar\drive\image\MARS_snapshot_05_$type_$disk.sna -h\\bar\drive\image\MARS_snapshot_05_$type_$disk.hsh
23:57:10 Disks in backup:
23:57:10 C: -> \\bar\drive\image\MARS_snapshot_05_dif_C.sna
23:57:10 HD1:1 -> \\bar\drive\image\MARS_snapshot_05_dif_HD1-1.sna
23:57:10 Preparing for backup
23:57:10 Drive HD1:1 is not supported by the Volume Shadow copy service
23:57:23 No exchange writer involved, using internal backup engine
23:57:24 Start differential backup of C: -> \\bar\drive\image\MARS_snapshot_05_dif_C.sna
23:57:24 free space info: total 244.095MB, 199.181MB free, 43.698MB must be saved
23:57:24 C: -> \\bar\drive\image\MARS_snapshot_05_dif_C.sna
23:59:11 4 sectors need more than 100ms to read
23:59:11 C: 44.914MB in use - stored in 26.228KB - 1:47 minutes
23:59:11 Success
23:59:11 Start verification of: \\bar\drive\image\MARS_snapshot_05_dif_C.sna
23:59:12 Success!
23:59:12 Start differential backup of HD1:1 -> \\bar\drive\image\MARS_snapshot_05_dif_HD1-1.sna
23:59:12 free space info: total 102.396KB, 75.424KB free, 26.972KB must be saved
23:59:13 HD1:1 -> \\bar\drive\image\MARS_snapshot_05_dif_HD1-1.sna
23:59:13 HD1:1 26.972KB in use - stored in 1.040KB - 0:00 minutes
23:59:13 Success
23:59:13 Start verification of: \\bar\drive\image\MARS_snapshot_05_dif_HD1-1.sna
23:59:13 Success!
23:59:13 Snapshot finished successfully
23:59:13 End of Snapshot 1.48 [May 6 2021] at 25.05.2021
[2021.05.25 (23:59:13)] INFO: END of BACKUP with result SUCCESS !
[2021.05.25 (23:59:13)] return=0
[2021.05.25 (23:59:13)] INFO: sending mail to: michael@schmidt2.de
[2021.05.25 (23:59:13)] INFO: MailServer = smtp.gmail.com
[2021.05.25 (23:59:14)] INFO: mail sent
```

BIN
snapcontrol.exe Normal file

Binary file not shown.

112
snapcontrol.ini Normal file
View File

@ -0,0 +1,112 @@
; SNAPCONTROL config file.
; https://github.com/mhgschmidt/snapcontrol
;
; This tool creates an image backups of windows machines,
; it uses the Drive Snapshot tool by Tom Ehlert Software.
; Please support this great tool and buy a license.
; http://www.drivesnapshot.de/en/order.htm
;
; Copyright (c) 2019-2021 Michael H.G. Schmidt
; EMAIL: michael@schmidt2.de
; Released under the MIT license.
;
; IMPORTANT: DO NOT USE quotation marks in this INIFILE !
;
[INSTALL]
; where to install the exe and the infile ...
InstallTo = c:\snapshot
; path where snapshot.exe is located ...
BinPath = c:\tools
[BACKUP]
; target PATH examples:
; - "D:\BACKUP" (LOCAL path on drive d:)
; - "\\example\share" (SMB share on server "example")
; - "/backup" (some path on FTP server)
TargetPath = D:\BACKUP
; active FTP backup with "yes"
FtpBackup = no
; name of ftp server
FtpServer = ftp.example.com
; target USER (only for SMB/FTP mode needed)
TargetUser = ftpbackup
; target PASSWORD (only for SMB/FTP mode needed)
TargetPassword = mypassword
; backup schedule modes:
; TIME -> absolute start time (format = hh:mm)
; LOGIN -> delay before starting the backup after login (format = mmmm:ss)
BackupSched = LOGIN
BackupStart = 0005:00
; disks to dump (please use Drive Snapshot format!)
; see http://www.drivesnapshot.de/en/commandline.htm
Disks2Dump = HD1:*
; maximum size of dumpfiles in MB (reduce for fat32 target drives to 4095)
DumpSize = 4095
; verify the backup ?
Verify = yes
; delete all files in the recycle bin before starting the backup ?
BurnTrash = no
; encrypt the backup ?
; no: do NOT encrypt
; dynamic: generate a password. will be sent via mail
; HINT: Generation happens only ONCE and only in case
; that "encryptpw" ist empty. snapcontrol will write
; the generated password into the inifile !
; yes: use the password in variable "encryptpw"
Encrypt = no
; some hard to guess password ---> WRITE IT DOWN !!!
; and DO NOT USE quotation marks !
EncryptPW =
; limit write IO in MB/s
LimitIO =
; should drive/media be ejected after backup ? (yes/no)
EjectMedia = yes
[LOGGING]
LogFile = backup.log
HistLog = history.log
[MAIL]
;
; The mail setup in this config file was tested and works perfectly
; for gmail (please be aware that you will have to change your
; gmail security settings in case you plan to use gmail)
;
; shall we send a mail ?
MailReport = no
; mail recipient...
MailTo = backup@example.com
; address of SMTP server (TLS/SSL only !)
MailServer = smtp.gmail.com
; port of SMTP server (in most cases it's 465 or 587)
MailPort = 465
; user for sending mail
MailUser = example@gmail.com
; password on mailserver
MailPass = mypassword

540
snapcontrol.pb Normal file
View File

@ -0,0 +1,540 @@
; snapcontrol.pb
; https://github.com/mhgschmidt/snapcontrol
; ------------------------------------------------------------
; Drive snapshot backup controller
; - starts backups using drive snapshot
; - sends reports via email
; LICENSE : MIT License
; AUTHOR : Michael H.G. Schmidt
; EMAIL : michael@schmidt2.de
; DATE : 20210526
; ------------------------------------------------------------
;
; This tool creates an image backups of windows machines,
; it uses the Drive Snapshot tool by Tom Ehlert Software.
; Please support this great tool and buy a license.
; http://www.drivesnapshot.de/en/order.htm
;
; Copyright (c) 2019-2021 Michael H.G. Schmidt
; Released under the MIT license.
;
;
; INIT (set vars, read args, read inifile etc. pp.)
;
OpenConsole()
EnableGraphicalConsole(0)
Dim filelist$(0)
Global VERSION$="V1.02"
Global installme = 0
Global updatesched = 0
Global dryrun = 0
Global hostname$ = GetEnvironmentVariable("COMPUTERNAME")
Global jobname$ = "snapcontrol"
Global month$ = FormatDate("%mm", Date())
Global day$ = FormatDate("%dd", Date())
Global DriveSnapshotVersionOk = 0
; valid versions for Drive Snapshot we support ...
NewList DriveSnapshotVersion$()
AddElement(DriveSnapshotVersion$())
DriveSnapshotVersion$() = "V1.46"
AddElement(DriveSnapshotVersion$())
DriveSnapshotVersion$() = "V1.47"
AddElement(DriveSnapshotVersion$())
DriveSnapshotVersion$() = "V1.48"
Procedure Usage()
PrintN ("usage: snapcontrol.exe </I | /U | /D | /V>")
PrintN (" /I = install program and config")
PrintN (" /U = update scheduler job")
PrintN (" /D = dry run")
PrintN (" /V = show version")
End 99
EndProcedure
; check commandline...
If ( CountProgramParameters() >1 )
Usage()
EndIf
; set path for inifile ...
inifile$ = RTrim(GetPathPart(ProgramFilename()),"\") + "\snapcontrol.ini"
; install job, update job, show version, dry run ...
If ( UCase(ProgramParameter(0)) = "/I" )
installme = 1
ElseIf ( UCase(ProgramParameter(0)) = "/U" )
updatesched = 1
ElseIf ( UCase(ProgramParameter(0)) = "/V" )
PrintN ("Version = " + VERSION$)
End 0
ElseIf ( UCase(ProgramParameter(0)) = "/D" )
dryrun = 1
ElseIf ( UCase(ProgramParameter(0)) = "/?" )
Usage()
EndIf
; Procedure "RunProgram" aborts after writing approx. 8GB data with snapshot64...
; so we will use native "system" command...
ImportC "msvcrt.lib"
system(str.p-ascii)
EndImport
If (Not OpenPreferences(inifile$))
PrintN ("FATAL: cannot read inifile [ " + inifile$ + " ] ---> EXIT.")
End 98
EndIf
PreferenceGroup("install")
Global InstallTo$ = ReadPreferenceString("InstallTo","c:\snapshot")
Global BinPath$ = ReadPreferenceString("BinPath","c:\tools")
PreferenceGroup("backup")
Global TargetPath$ = ReadPreferenceString("TargetPath","\\server\share")
Global FtpBackup$ = ReadPreferenceString("FtpBackup","no")
Global FtpServer$ = ReadPreferenceString("FtpServer","none")
Global TargetUser$ = ReadPreferenceString("TargetUser","guest")
Global TargetPassword$ = ReadPreferenceString("TargetPassword","guest")
Global BackupschedMode$ = ReadPreferenceString("BackupschedMode","LOGIN")
Global BackupStart$ = ReadPreferenceString("BackupStart","0005:00")
Global Disks2Dump$ = ReadPreferenceString("Disks2Dump","HD1:*")
Global DumpSize$ = ReadPreferenceString("DumpSize","4095")
Global Verify$ = ReadPreferenceString("Verify","yes")
Global BurnTrash$ = ReadPreferenceString("BurnTrash","no")
Global Encrypt$ = ReadPreferenceString("Encrypt","no")
Global EncryptPW$ = ReadPreferenceString("EncryptPW","")
Global LimitIO$ = ReadPreferenceString("LimitIO","")
Global EjectMedia$ = ReadPreferenceString("EjectMedia","yes")
PreferenceGroup("logging")
Global LogFile$ = ReadPreferenceString("LogFile","backup.log")
Global HistLog$ = ReadPreferenceString("HistLog","history.log")
; add PATH to logfiles ...
LogFile$ = InstallTo$ + "\" + LogFile$
HistLog$ = InstallTo$ + "\" + HistLog$
PreferenceGroup("mail")
Global MailReport$ = ReadPreferenceString("MailReport","no")
Global MailTo$ = ReadPreferenceString("MailTo","")
Global MailServer$ = ReadPreferenceString("MailServer","")
Global MailPort = Val(ReadPreferenceString("MailPort",""))
Global MailUser$ = ReadPreferenceString("MailUser","")
Global MailPass$ = ReadPreferenceString("MailPass","")
; which Drive Snapshot version should be used ?
arch$ = GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
If ( arch$ = "x86" )
SnapshotBin$ = BinPath$ + "\snapshot.exe"
Else
SnapshotBin$ = BinPath$ + "\snapshot64.exe"
EndIf
; Drive Snapshot found ?
If ( FileSize ( SnapshotBin$ ) < 0 )
PrintN("ERROR: [ " + SnapshotBin$ + " ] NOT found.")
End 1
EndIf
; Version check for Drive Snapshot ...
DriveSnapshot = RunProgram(SnapshotBin$, "/?", "", #PB_Program_Open | #PB_Program_Read)
If DriveSnapshot
While ProgramRunning(DriveSnapshot)
Out$ = Out$ + ReadProgramString(DriveSnapshot)
Wend
CloseProgram(DriveSnapshot)
EndIf
ForEach DriveSnapshotVersion$()
If ( FindString(Out$, DriveSnapshotVersion$()) >0 )
DriveSnapshotVersionOk = 1
Break
EndIf
Next
If ( DriveSnapshotVersionOk = 0 )
PrintN("ERROR: Drive Snapshot version is NOT supported!")
PrintN(" Supported versions are:")
ForEach DriveSnapshotVersion$()
PrintN(" - " + DriveSnapshotVersion$())
Next
End 1
EndIf
;
; PROCEDURES
;
Procedure LogMe(Message$)
Protected h = OpenFile(#PB_Any, LogFile$,
#PB_File_Append | #PB_File_NoBuffering | #PB_Ascii | #PB_File_SharedRead)
If h
WriteStringN(h, FormatDate("[%yyyy.%mm.%dd (%hh:%ii:%ss)] ", Date()) + Message$)
PrintN(FormatDate("[%yyyy.%mm.%dd (%hh:%ii:%ss)] ", Date()) + Message$)
CloseFile(h)
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Procedure LogMeRaw(Message$)
Protected h = OpenFile(#PB_Any, LogFile$,
#PB_File_Append | #PB_File_NoBuffering | #PB_Ascii | #PB_File_SharedRead)
If h
WriteStringN(h, Message$)
PrintN(Message$)
CloseFile(h)
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Procedure IsAdmin()
ProcedureReturn(system("reg.exe ADD HKLM /F >nul 2>&1"))
EndProcedure
Procedure LogSend(subject$, filename$)
InitNetwork()
Protected e = 0
Protected MailText$ = ""
If CreateMail(0, "system@" + hostname$ , subject$)
AddMailRecipient(0, MailTo$, #PB_Mail_To)
LogMe("INFO: MailServer = " + Mailserver$)
If ReadFile(0, filename$, #PB_File_SharedRead)
While Eof(0) = 0
MailText$ + ReadString(0) + Chr($0d) + Chr($0a)
Wend
CloseFile(0)
SetMailBody(0, MailText$)
EndIf
; send mails ALWAYS with SSL...
e = SendMail(0, MailServer$, MailPort, #PB_Mail_UseSSL, MailUser$, MailPass$)
EndIf
ProcedureReturn e
EndProcedure
Procedure EndProg(err)
Protected s$ = ""
If ( err = 0 )
LogMe("INFO: END of BACKUP with result SUCCESS !")
s$ = "BACKUP report - { SUCCESS } @" + hostname$
Else
LogMe("ERROR: END of BACKUP with result FAILED !")
s$ = "BACKUP report - { ERROR ! } @" + hostname$
EndIf
; write return code of last command (snapshot.exe) to logfile
LogMe("return=" + err)
; send a report via mail ?
If ( LCase(MailReport$) = "yes" )
LogMe("INFO: sending mail to: " + MailTo$)
If ( LogSend(s$, Logfile$) )
LogMe("INFO: mail sent")
Else
LogMe("FATAL: could not send backup report via email...")
LogMeRaw(" please inform your Administrator !")
EndIf
EndIf
; adding actual logfile to histlog...
If ReadFile(0, Logfile$, #PB_File_SharedRead)
While Eof(0) = 0
LogText$ + ReadString(0) + Chr($0d) + Chr($0a)
Wend
CloseFile(0)
EndIf
If OpenFile(0, HistLog$, #PB_File_Append | #PB_File_NoBuffering | #PB_File_SharedRead )
FileSeek(0, Lof(0))
WriteString(0,LogText$)
CloseFile(0)
EndIf
; remove backup share...
dummy = system("net use " + TargetPath$ + " /DELETE >nul 2>&1")
ClosePreferences()
CloseConsole()
End err
EndProcedure
Procedure.s mkpass(password_length)
chars$ = "abcdef-" ; possible characters, keep these lcase
For a = 1 To password_length
Select Random(1) ; 0 = char, 1 = digit
Case 1 ; is digit
pass$ + Str(Random(9))
Case 0 ; is character
position = Random(Len(chars$)) ; random character selector
pass$ + Mid(chars$,position,1)
EndSelect
Next
ProcedureReturn pass$
EndProcedure
;
; MAIN
;
; installation requested ?
If ( installme = 1 )
; delete old logfiles ...
LogMe("INFO: deleting old logfiles ...")
dummy = system("del /F /Q " + LogFile$ + " 2>nul")
dummy = system("del /F /Q " + HistLog$ + " 2>nul")
; create directory ...
LogMe("INFO: creating directory [ " + InstallTo$ + " ] ...")
dummy = system("mkdir " + InstallTo$ + " >nul 2>&1")
; copy binary and inifile ...
LogMe("INFO: copy binary and inifile to folder [ " + InstallTo$ + " ] ...")
dummy = system("copy /Y " + inifile$ + " " + InstallTo$ + " 2>nul")
dummy = system("copy /Y " + ProgramFilename() + " " + InstallTo$ + " 2>nul")
; update jobscheduler (selfcall) ...
dummy = system(InstallTo$ + "\snapcontrol.exe /U 2>nul")
ClosePreferences()
CloseConsole()
End
EndIf
; update for jobscheduler requested ?
If ( updatesched = 1 )
username$ = GetEnvironmentVariable("USERNAME")
; generate call string for task...
jobcmd$ = ProgramFilename()
; check jobtype ...
If ( LCase(BackupschedMode$) <> "login" And LCase(BackupschedMode$) <> "time" )
PrintN("WARNING: unknown BackupschedMode [ " + BackupschedMode$ + " ] ---> IGNORING. Type will be set to LOGIN.")
BackupschedMode$ = "LOGIN"
EndIf
; update the job ...
PrintN ("Updating windows jobscheduler ...")
If ( LCase(BackupschedMode$) = "time" )
dummy = system("schtasks /create /F /RL HIGHEST /SC daily /ST " + BackupStart$ + " /TN " + jobname$ + " /TR " + jobcmd$)
ElseIf ( LCase(BackupschedMode$) = "login" )
dummy = system("schtasks /create /F /RL HIGHEST /SC onlogon /DELAY " + BackupStart$ + " /TN " + jobname$ + " /TR " + jobcmd$)
EndIf
; show job and print some status messages...
dummy = system("schtasks /query /FO List /V /TN " + jobname$)
PrintN (Chr(13) + "READY." + Chr(13))
ClosePreferences()
CloseConsole()
End
EndIf
;
; ASK the user for permission to start ...
;
; FTP backup requested ?
If ( FtpBackup$ = "yes" )
TargetPath$ = "ftp://" + TargetUser$ + "@" + FtpServer$ + TargetPath$
EndIf
Result = MessageRequester("SnapControl",
"Start BACKUP now?" + Chr(13) +
"Targetpath => " + TargetPath$,
#PB_MessageRequester_YesNo | #PB_MessageRequester_Info)
If Result = #PB_MessageRequester_No
Result = MessageRequester("SnapControl",
"backup ABORTED.",
#PB_MessageRequester_Ok | #PB_MessageRequester_Warning)
CloseConsole()
End 0
EndIf
; cleanup: delete old Logfile, remove old drive letter...
dummy = DeleteFile(LogFile$, #PB_FileSystem_Force)
LogMe("============== starting BACKUP ==============")
LogMe("snapcontrol.exe version = [ " + VERSION$ + " ]")
LogMe(" snapshot.exe version = [ " + DriveSnapshotVersion$() + " ]")
If ( dryrun = 1 )
LogMe("DRYRUN - (simulating a backup run) !!!")
EndIf
e = IsAdmin()
If ( e = 0 )
LogMe("OK. Running as Admin ...")
Else
PrintN("ERROR: Please run as Administrator !")
PrintN(" cannot continue ---> EXIT")
End 97
EndIf
;
; GENERATE the BACKUP command...
;
; encryption enabled ?
If ( LCase(Encrypt$) = "yes" )
params$ = "-PW=" + EncryptPW$ + " "
If ( EncryptPW$ = "" )
LogMe("WARNING: ENCRYPTED backup requested but PASSWORD is not set in infile !")
Else
LogMe("WARNING: encryption requested. The backup will be encrypted.")
LogMeRaw(" --> PLEASE WRITE DOWN YOUR PASSWORD AND STORE IT IN A SAFE PLACE !")
EndIf
EndIf
If ( LCase(Encrypt$) = "dynamic" )
If ( EncryptPW$ = "" )
EncryptPW$ = mkpass(20)
LogMe("WARNING: ENCRYPTED backup requested and DYNAMIC password was requested !")
LogMeRaw(" Generated password is: --->>> " + EncryptPW$ + " <<<---")
LogMe("INFO: writing password to inifile...")
PreferenceGroup("Global")
dummy = WritePreferenceString("EncryptPW", EncryptPW$)
Else
LogMe("WARNING: ENCRYPTED backup requested. Using DYNAMIC password in inifile !")
LogMeRaw(" The password is: --->>> " + EncryptPW$ + " <<<---")
EndIf
params$ = "-PW=" + EncryptPW$ + " "
EndIf
; limit the write rate ?
If ( LimitIO$ <> "" )
params$ + "--LimitIORate:" + LimitIO$ + " "
EndIf
; verify the backup ?
If ( LCase(Verify$) = "yes" )
params$ + "-T "
EndIf
; burn all the trash in the recyclebin ?
If ( LCase(BurnTrash$) = "yes" )
params$ + "-R "
EndIf
; eject media ?
If ( EjectMedia$ = "yes" )
params$ + "--EjectDriveAfterBackup "
EndIf
; FTP backup requested ?
If ( FtpBackup$ = "yes" )
LogMe("INFO: FTP backup, using server [ " + FtpServer$ + " ] for backup ...")
; add ftp account ...
e = system(SnapshotBin$ + " --AddFTPAccount:" + TargetUser$ + "," + FtpServer$ + "," + TargetPassword$)
; generate filenames for backup ...
DumpFile$ = TargetPath$ + "/" + hostname$ + "_snapshot_" + month$ + "_$type_$disk.sna"
HashFile$ = "-h" + InstallTo$ + "\" + hostname$ + "_snapshot_" + month$ + "_$type_$disk.hsh"
Else
; network share or local drive ?
colonpos = FindString(TargetPath$, ":")
If ( colonpos = 0 )
; no colon found in path this means we are using a network share ...
params$ + "--NetUse:" + TargetPath$ + "," + TargetUser$ + "," + TargetPassword$ + " "
LogMe("INFO: using a NETWORK share for backup ...")
Else
; found a ':' at some position means we are using a drive letter ...
DRIVE$ = Left(TargetPath$, colonpos)
LogMe("INFO: using DRIVE [ " + DRIVE$ + " ] for backup ...")
EndIf
; check if there is a full backup file ... in case it was deleted ...
If ( FileSize ( TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_ful*.sna" ) < 0 )
LogMe("WARNING: no full backup found.")
If ( FileSize ( TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_ful*.hsh" ) >= 0 )
dummy = system("del /F /Q " + TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_ful*.hsh")
LogMe("INFO: [ " + TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_ful*.hsh ] deleted.")
EndIf
EndIf
; check the actual FULL backup file for errors ...
; ( must be done BEFORE we run a backup because we don't know - for sure
; - wether the last backup was interrupted or not... )
i = 1
If ExamineDirectory(0, TargetPath$, hostname$ + "_snapshot_" + month$ + "_ful*.sna")
While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_File
ReDim filelist$(i)
filelist$(i-1) = DirectoryEntryName(0)
LogMe("INFO: found [ " + filelist$(i-1) + " ]")
i + 1
EndIf
Wend
FinishDirectory(0)
EndIf
e = 0
For i = 1 To ArraySize(filelist$())
LogMe("INFO: Starting QUICKCHECK for [ " + filelist$(i-1) + " ]")
e = system(SnapshotBin$ + " --Logfile:" + LogFile$ + " --QuickCheck:" + TargetPath$ + "\" + filelist$(i-1))
If ( e <> 0 )
LogMe("ERROR: DELETING last full backup [ REASON: corrupt file! ]")
dummy = system("del /F /Q " + TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_ful*.*")
Break
EndIf
Next i
; generate filenames for backup ...
DumpFile$ = TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_$type_$disk.sna"
HashFile$ = "-h" + TargetPath$ + "\" + hostname$ + "_snapshot_" + month$ + "_$type_$disk.hsh"
EndIf
;
; run BACKUP...
;
; extend params ...
params$ + " --FullIfHashIsMissing --CreateDir -W -L" + DumpSize$ + " " + Disks2Dump$
LogMe("INFO: executing command [ " + SnapshotBin$ + " ]")
LogMe(" DumpFile: [ " + DumpFile$ + " ]")
LogMe(" HashFile: [ " + HashFile$ + " ]")
LogMe(" LogFile: [ " + LogFile$ + " ]")
If ( dryrun = 0 )
e = system(SnapshotBin$ + " --Logfile:" + LogFile$ + " " + params$ + " " + DumpFile$ + " " + HashFile$)
EndIf
; end with return code...
EndProg(e)
; IDE Options = PureBasic 5.73 LTS (Windows - x64)
; ExecutableFormat = Console
; CursorPosition = 58
; FirstLine = 20
; Folding = --
; EnableXP
; Executable = snapcontrol.exe
; DisableDebugger
; Warnings = Display