-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwpkgsync.bat
More file actions
257 lines (225 loc) · 11.5 KB
/
wpkgsync.bat
File metadata and controls
257 lines (225 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
@echo off
rem obtain cwrsync from https://www.itefix.net/content/cwrsync-free-edition
rem create user id file using ssh-keygen
rem put public part on server, and private part at %wpkgidfile%
rem schedule this file to run
rem file needs to run as Admin equivalent, or wpkguserdetails and rsync logging to logfile won't work
rem 1. make sure this is the only wpkgsync process runs at a time
rem 2. don't start if wpkg service is running
rem 3. except that we are launched from end of wpkg service, so that's allowed
rem 4. if sync was successful, record date, so that another process can alarm if we've failed for a long time.
rem todo alert if we haven't managed to synch in 14 days:
rem forfiles /P c:\ProgramData\wpkgsync\ /m lastsync.log /D -14
rem if errorlevel 1 something...
rem call:
rem /fast - don't speed limit (default 2,000Kbps)
rem /setup just do the minimum - top level
rem /dryrun pretend to do sync
rem returned codes:
rem 101 missing ini file
rem 102 could not read from ini file
rem 103 FIX_ACLS failed
rem 104 not running as Admin
rem 200+rsync get failed
rem 300+rsync send failed
rem other setup rsync failed
rem changelog
rem 20/10/16 dce tidy up
rem 13/07/17 dce id file in .ssh
rem 04/01/18 dce new version of cwrsync, log sending of wpkg log file
rem fix received file permissions
rem add -o UserKnownHostsFile=%wpkg_hosts%
rem 08/01/18 dce fix takeown and icacls syntax
rem 21/05/18 dce append username to log file, derive rsync wpkglogfile from DOS version
rem 17/09/18 dce add /fast option
rem 21/10/18 dce add required --times option to rsync
rem 26/02/20 dce use any relevant packages\exclude file, delete-excluded
rem 11/03/20 dce site specific variables in .ini file
rem 29/04/20 dce add /setup
rem 07/05/20 dce use the new way of getting last user and boot time
rem 12/05/20 dce grant users RX on the folder too
rem 15/05/20 dce use wmic for boot time as it's locale independent
rem LastLoggedOnUser gives just as good results as the script we were using
rem 02/07/20 dce autogenerate exclude file
rem 03/07/20 dce abort if not running as Admin, tidy up variables
rem 09/11/20 dce get systeminfo and serial number
rem 23/11/20 dce we'll get wpkg to run "logfile" now, so we just need to deal with the output
rem 27/12/20 dce fail statuses for rsync get and rsync send, append wpkgExtras.tmp to log once only
rem 07/03/21 dce allow only one instance to run, don't run if WPKG Service is running.
rem 14/03/21 dce write last success at end
rem 17/03/22 dce at FIX_ACLS section add DE variants of commands
rem 18/03/22 dce remove extraneous code re acl.log
rem 03/07/23 dce move .ini file to %programdata%\wpkgsync\ and store more variables there
rem 04/07/23 dce add /dryrun
rem abort if not running as Admin
net file >nul 2>&1
if errorlevel 1 (
echo this script must run as Admin / Dieses Skript muss als Administrator ausgeführt werden
exit /b 104
)
rem make sure we are OK to run, is wpkgsync_process already running?
tasklist | find /i "rsync" >nul 2>&1 && goto END
rem if WPKG service is not running, we can begin.
net start | find /i "wpkg" || goto BEGIN
rem if WPKG service is running then re-launch ourself as a separate instance
if not "%running%"=="" goto WAITCHECK
set running=true
start "WPKGsync Script" /separate %0
exit
:WAITCHECK
rem if WPKG service is not running, then we can begin, wait for 5 seconds
echo wait 5 seconds...
ping -n 5 localhost > nul
rem and if it is still running, then quit because we're not alone.
net start | find /i "wpkg" && exit
:BEGIN
rem Make environment variable changes local to this batch file
SETLOCAL
rem Specify where to find rsync and related files, and add to PATH
set CWRSYNCHOME=%~dp0
set PATH=%CWRSYNCHOME%;%PATH%
rem save these because %~0 will be destroyed by shift
set scriptname=%~n0
set scriptpath=%~dp0
set inifile=%programdata%\%~n0\%~n0.ini
rem load variables from the .ini file, use usebackq otherwise quoted path is interpreted as a string
if exist "%inifile%" (
FOR /F "usebackq tokens=1,2 delims==" %%i in ("%inifile%") do (
if "%%i"=="wpkgremote" set wpkgremote=%%j
if "%%i"=="wpkgreports" set wpkgreports=%%j
if "%%i"=="wpkgfolder" set wpkgfolder=%%j
if "%%i"=="wpkgidfile" set wpkgidfile=%%j
if "%%i"=="wpkg_hosts" set wpkg_hosts=%%j
if "%%i"=="wpkglocal" set wpkglocal=%%j
)
) else (
echo missing file "%inifile%"
exit /b 101
)
rem check we got the values we need
if "%wpkgremote%"=="" goto INIERROR
if "%wpkgreports%"=="" goto INIERROR
if "%wpkgidfile%"=="" goto INIERROR
if "%wpkg_hosts%"=="" goto INIERROR
if "%wpkgfolder%"=="" goto INIERROR
if "%wpkglocal%"=="" goto INIERROR
rem we're required to set HOME, but it seems to be ignored
set HOME=%ProgramData%\wpkgsync
set wpkglogfile=%systemdrive%\wpkg-%computername%.log
rem now parse any parameters
set bwlimit=--bwlimit=2000
set setup=
:PARSE
if /i '%1'=='/fast' set bwlimit=
if /i '%1'=='/setup' set setup=True
if /i '%1'=='/dryrun' set dryrun=--dry-run
shift
rem loop until we've consumed all the parameters passed
if not '%1'=='' goto PARSE
rem rsync/ssh options
rem -r recurse into folders
rem -n dry run
rem -v verbose
rem -h human readable numbers
rem -e use this shell
rem -i use this identity file
rem -o UserKnownHostsFile= use this KnownHosts file
rem --delete files here which don't exist at the source end
rem --delete-excluded also delete excluded files from dest dirs, this would delete the client files, but we don't need them any more
rem --timeout=seconds
rem --exclude=PATTERN exclude files matching PATTERN
rem --exclude-from=file read exclude patterns from FILE
rem --partial keep partially transferred files
rem --times transmit file modification time, so subsequent checks can use this instead of file compare.
rem --bwlimit=KBPS limit I/O bandwidth; KBytes per second
rem 0 Success
rem 1 Syntax or usage error
rem 2 Protocol incompatibility
rem 3 Errors selecting input/output files, dirs
rem 4 Requested action not supported (by the client and not by the server)
rem 5 Error starting client-server protocol
rem 6 Daemon unable to append to log-file
rem 10 Error in socket I/O
rem 11 Error in file I/O
rem 12 Error in rsync protocol data stream
rem 13 Errors with program diagnostics
rem 14 Error in IPC code
rem 20 Received SIGUSR1 or SIGINT
rem 21 Some error returned by waitpid()
rem 22 Error allocating core memory buffers
rem 23 Partial transfer due to error
rem 24 Partial transfer due to vanished source files
rem 25 The --max-delete limit stopped deletions
rem 30 Timeout in data send/receive
rem 35 Timeout waiting for daemon connection
rem can't talk to the remote server will result in code 12
rem can't find the file/folder you're after will result in code 23
:SETUP
if '%setup%'=='' goto MAKE-EXCLUDE-FILE
rem just the top level, no packages as yet, no logging, because we'll be running this whilst wpkg is active
rem if it failed then abort, so that automated install will abort
set exclude=--exclude='profiles.sites' --exclude='packages/'
rsync %dryrun% -r -e "ssh -i %wpkgidfile% -o UserKnownHostsFile=%wpkg_hosts%" --partial --times --timeout=120 %bwlimit% %exclude% %wpkgremote%/ %wpkglocal%/ >nul 2>&1
if errorlevel 1 exit /b %errorlevel%
rem and the package.xml files, so we can process excludes later
rsync %dryrun% -e "ssh -i %wpkgidfile% -o UserKnownHostsFile=%wpkg_hosts%" --partial --times --timeout=120 %bwlimit% %wpkgremote%/packages/*.xml %wpkglocal%/packages/ >nul 2>&1
if errorlevel 1 exit /b %errorlevel%
rem and skip all the next bits
goto FIX_ACLS
:MAKE-EXCLUDE-FILE
if exist "%temp%\%scriptname%.excl.txt" del "%temp%\%scriptname%.excl.txt"
if not exist %wpkgFolder%\Tools\awk.exe goto RSYNC-GET
if not exist %wpkgFolder%\scripts\wpkgsyncexclude.awk goto RSYNC-GET
"%wpkgFolder%\Tools\awk.exe" -f %wpkgFolder%\scripts\wpkgsyncexclude.awk %wpkgFolder%\packages\*.xml %wpkglogfile% > "%temp%\%scriptname%.excl.txt"
:RSYNC-GET
rem if previous step has made an exclude file then use it, exclude-from works with DOS syntax too
set exclude=--exclude='profiles.sites' --exclude='client/'
if exist "%temp%\%scriptname%.excl.txt" set exclude=--exclude-from=%temp%\%scriptname%.excl.txt
rem sync the remote structure to here, append the log to the wpkg log (wpkg creates a new one each time):
rsync %dryrun% -rvh -e "ssh -i %wpkgidfile% -o UserKnownHostsFile=%wpkg_hosts%" --progress --delete --delete-excluded --partial --times --timeout=120 %bwlimit% %exclude% --log-file=%wpkglogfile% %wpkgremote%/ %wpkglocal%/ 2>nul
if errorlevel 1 set /a sync_get=200+%errorlevel%
:APPEND-LOG
rem if our logfile script has made an extra file, append that to the log, remove it so it only happens once
if exist "%temp%\wpkgExtras.tmp" type "%temp%\wpkgExtras.tmp" >> "%wpkglogfile%"
if exist "%temp%\wpkgExtras.tmp" del "%temp%\wpkgExtras.tmp"
if exist "%windir%\temp\wpkgExtras.tmp" type "%windir%\temp\wpkgExtras.tmp" >> "%wpkglogfile%"
if exist "%windir%\temp\wpkgExtras.tmp" del "%windir%\temp\wpkgExtras.tmp"
:RSYNC-SEND
rem set wpkglogfile for rsync, add /cygdrive/ and remove colons
set wpkglogfile=/cygdrive/%wpkglogfile::=%
rem replace \ with /
set wpkglogfile=%wpkglogfile:\=/%
rem should end up with e.g. wpkglogfile=/cygdrive/c/wpkg-%computername%.log
rem and send the wpkglogfile
rsync %dryrun% -vh -e "ssh -i %wpkgidfile% -o UserKnownHostsFile=%wpkg_hosts%" --timeout=120 %bwlimit% --log-file=%wpkglogfile% %wpkglogfile% %wpkgreports%/ 2>nul
if errorlevel 1 set /a sync_send=300+%errorlevel%
:FIX_ACLS
echo ##############################################################
echo %scriptpath%
echo ##############################################################
rem the commands we're using here are language dependant, simplest way to determine the relevant language to use is to use /?
echo setting file ownership on %wpkgfolder%...
echo setting file ownership on %wpkgfolder%... > "%temp%\%scriptname%_acl.log"
rem takeown to /Administrators group /Recurse /D prompt Y, send error out and cmd out to the log file
takeown /? | find /i "User" >nul && takeown /F %wpkgfolder%\* /A /R /D Y >> "%temp%\%scriptname%_acl.log" 2>&1
takeown /? | find /i "Benutzer" >nul && takeown /F %wpkgfolder%\* /A /R /D J >> "%temp%\%scriptname%_acl.log" 2>&1
set takeown=%errorlevel%
echo setting file permissions on %wpkgfolder%...
echo setting file permissions on %wpkgfolder%... >> "%temp%\%scriptname%_acl.log"
rem /T change Tree (recurse) /Grant, output to log file, apart from error text to CON which we can't capture
icacls /? | find /i "User" >nul && icacls %wpkgfolder%\* /T /grant:r "Administrators":F "SYSTEM":F "USERS":RX >> "%temp%\%scriptname%_acl.log" 2>&1
icacls /? | find /i "Benutzer" >nul && icacls %wpkgfolder%\* /T /grant:r "Administratoren":F "SYSTEM":F "Benutzer":RX >> "%temp%\%scriptname%_acl.log" 2>&1
set icacls=%errorlevel%
rem if there was an error
if not '%sync_get%'=='' exit /b %sync_get%
if not '%sync_send%'=='' exit /b %sync_send%
if '%takeown%.%icacls%'=='0.0' goto END
rem and quit
exit /b 103
:INIERROR
echo failed to initialise variables from "%inifile%"
exit /b 102
:END
if exist "%temp%\%scriptname%.acl.log" del "%temp%\%scriptname%.acl.log"
rem log the successful sync
echo %date% %time% %scriptname% sync success > %HOME%\lastsync.log