::
::  file: VSSMaint.cmd
::
:: blame: shardy@@differentchairs.com
::
:: Script to do routine maintenance on visual sourcesafe database.
:: ************************************************
:: (runs Analyze.exe against the VssDB1 VSS database on VssServer.)
::
:: Should ensure that no other program can lock any file in in the data hierarchy
::   (backups, virus checkers, sms...)
::
:: 1) Delete the share up front to force user disconnection.
:: 2) Make a local copy of the database.
:: 3) Run Analyze up to three times to correct problems found.
:: 4) Restore share.
::
:: Analyze puts its log info in data\backup\analyze.log
:: For each analyze run, we preserve the existing data\backup dir.
:: At the end of three runs:
::     data\backup.0\ is the original run,
::     data\backup.1\ is the next run, and
::     data\backup is the most recent run.
::
::     data.bak is a copy of the data dir, prior to the original run.
::     data.bak0 is a copy of data.bak from the previous maintenance cycle.
::
:: optional argument "-nocopy" prevents initial copy of data tree to data.bak\
::
:: This could be scheduled on VssServer via winat (in ntreskit) using this command:
::
::     c:\winnt\system32\cmd.exe /ce:\VssDB1\vssmaint\vssmaint.cmd
::
::

if /i not "%computername%"=="VssServer" goto :EOF

set sharename=\\VssServer\VssDB1
set basedir=\VssDB1
set localdatadir=%basedir%\data
set unlockDB=
set logfile=%basedir%\vssmaint\vssmaint.log
set maintainer=blackhole
set analyzePgm=%basedir%\vssmaint\analyze.exe
set skipcopy=
set vsslockfile=%localdatadir%\loggedin\admin.lck

if /i %1.==-nocopy. set skipcopy=1

cd /d %~dp0

time/t > %logfile%

if exist %vsslockfile% goto DB_locked
  set unlockDB=1
  echo.>%vsslockfile%

:DB_locked

:: remove user access to the VssDB1 share up front.
:: [ToDo:]  notify any connected users.
::
::          if (user connected)
::            foreach connected user
::              send message indicating upcoming disconnect
::            sleep 3 min
::          turn off share access
call :lockShare

if defined skipcopy goto copied
:: make copy of data directory
:: [ToDo:]    verify enough free space first...
if exist %localdatadir%.bak0 rd /s/q %localdatadir%.bak0
::    and, in case it's a file...
if exist %localdatadir%.bak0 del /f %localdatadir%.bak0

if exist %localdatadir%.bak ren %localdatadir%.bak data.bak0
::    and, in case it's a file...
if exist %localdatadir%.bak del /f %localdatadir%.bak
xcopy %localdatadir% %localdatadir%.bak\ /e

:copied
:: Empty or rename the data\backup directory. Otherwise, analyze fails.
if exist %localdatadir%\backup del /f /q %localdatadir%\backup
for %%i in (0 1) do if exist %localdatadir%\backup.%%i del /f /q %localdatadir%\backup.%%i
for %%i in (0 1) do if exist %localdatadir%\backup.%%i rd /s /q %localdatadir%\backup.%%i

echo Beginning first pass>>%logfile%
time/t >> %logfile%
%analyzePgm% %localdatadir% -v4 -f -i-

if exist %localdatadir%\backup\analyze.log (
  find "Writing" %localdatadir%\backup\analyze.log>nul || goto cleanup
  )

:: errors found. Do another pass
echo Error found on first pass. Beginning second pass>>%logfile%
ren %localdatadir%\backup backup.0
time/t >> %logfile%
%analyzePgm% %localdatadir% -v4 -f -i- -c -d

if exist %localdatadir%\backup\analyze.log (
  find "Writing" %localdatadir%\backup\analyze.log>nul || goto cleanup
  )

:: errors found. Do 1 more pass
echo Error corrected on Second pass. Beginning third pass>>%logfile%
ren %localdatadir%\backup backup.1
time/t >> %logfile%
%analyzePgm% %localdatadir% -v4 -f -i- -c -d

:cleanup
echo Done>>%logfile%
::
:: restore access to share when done
::

call :unlockShare
if defined unlockDB del %vsslockfile%
:: [ToDo:]  publish maintenance report...
find "No errors or inconsistencies found" %localdatadir%\backup\analyze.log
if not Errorlevel 1 goto done
NET send %maintainer% "VSS Maint Problem. Look at %sharename%\data\backup\analyze.log"
echo "VSS Maint Problem. Look at %sharename%\data\backup\analyze.log">>%logfile%
:done
time/t >> %logfile%

goto :EOF


:lockShare
::just changing permissions doesn't cut it.
::Analyze needs to have users explicitly disconnected.
::  rmtshare %sharename% /grant everyone:NONE
call :mkSharecmd %sharename%
rmtshare %sharename% /delete
goto :EOF

:unlockShare
::  rmtshare %sharename% /grant everyone:CHANGE
call reshare.cmd
goto :EOF

:mkSharecmd
set sharecmd=rmtshare %1
:: get the local share directory
for /f "tokens=2" %%a in ('rmtshare %1^|findstr /b "Path"') do (
  set sharecmd=%sharecmd%=%%a
  )

:: now get the current share permissions
for /f "tokens=*" %%a in ('rmtshare %1^|findstr /b /c:" "') do (
  for /f "tokens=1,3" %%b in ("%%a") do (
    @call :exec set sharecmd=%%sharecmd%% /grant %%b:%%c
    )
  )
echo %sharecmd%>reShare.cmd
goto :EOF

:exec
%*
goto :EOF