@ECHO off setlocal ENABLEDELAYEDEXPANSION REM REM REM Bacula interface to virtual autoloader using disk storage REM REM $Id: disk-changer.in,v 1.3 2006/07/30 16:00:32 kerns Exp $ REM REM If you set in your Device resource REM REM Changer Command = "disk-changer %c %o %S %a %d" REM you will have the following input to this script: REM REM So Bacula will always call with all the following arguments, even though REM in some cases, not all are used. REM REM disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" REM %1 %2 %3 %4 %5 REM REM By default the autochanger has 10 Volumes and 1 Drive. REM REM Note: For this script to work, you *must" specify REM Device Type = File REM in each of the Devices associated with your AutoChanger resource. REM REM changer-device is the name of a file that overrides the default REM volumes and drives. It may have: REM maxslot=n where n is one based (default 10) REM maxdrive=m where m is zero based (default 1 -- i.e. 2 drives) REM REM This code can also simulate barcodes. You simply put REM a list of the slots and barcodes in the "base" directory/barcodes. REM See below for the base directory definition. Example of a REM barcodes file: REM C:\TEMP\bacula\barcodes REM 1:Vol001 REM 2:Vol002 REM ... REM REM archive-device is the name of the base directory where you want the REM Volumes stored appended with \drive0 for the first drive; \drive1 REM for the second drive, ... For example, you might use REM C:\Temp\bacula\drive0 Note: you must not have a trailing slash, and REM the string (e.g. \drive0) must be unique, and it must not match REM any other part of the directory name. These restrictions could be REM easily removed by any clever script jockey. REM REM Full example: disk-changer C:\Temp\bacula\conf load 1 C:\Temp\bacula\drive0 0 REM REM The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the REM base directory. In the above example the base directory is C:\Temp\bacula. REM However, as with tapes, their Bacula Volume names will be stored inside the REM Volume label. In addition to the Volumes (e.g. C:\Temp\bacula\slot1, REM C:\Temp\bacula\slot3, ...) this script will create a C:\Temp\bacula\loadedn REM file to keep track of what Slot is loaded. You should not change this file. REM SET dbgfile=%CD%\disk-changer.log REM to turn on logging, uncomment the following line IF NOT EXIST %dbgfile% COPY nul %dbgfile% >nul REM REM check parameter count on commandline REM REM Check for special cases where only 2 arguments are needed, REM all others are a minimum of 5 REM IF "%1" EQU "" goto :param_count_invalid IF "%2" EQU "" goto :param_count_invalid IF "%2" EQU "list" goto :param_count_valid IF "%2" EQU "slots" goto :param_count_valid IF "%3" EQU "" goto :param_count_invalid IF "%4" EQU "" goto :param_count_invalid IF "%5" EQU "" goto :param_count_invalid GOTO :param_count_valid :param_count_invalid echo Insufficient number of arguments given. IF "%2" EQU "" ( echo At least two arguments must be specified. ) else echo Command expected 5 arguments. :usage ECHO. ECHO usage: disk-changer ctl-device command [slot archive-device drive-index] ECHO Valid commands are: unload, load, list, loaded, and slots. EXIT /B 1 :param_count_valid REM Setup arguments SET ctl=%1 SET cmd=%2 SET slot=%3 SET device=%4 SET drive=%5 REM set defaults SET maxdrive=1 SET maxslot=10 SET ctl=%ctl:/=\% SET ctl=%ctl:\\=\% SET device=%device:/=\% SET device=%device:\\=\% REM Pull in conf file IF EXIST %ctl% CALL %ctl% FOR %%i IN ( %ctl% ) DO SET dirname=%%~dpi IF NOT EXIST %dirname%nul ( ECHO ERROR: Autochanger directory "%dirname%" does not exist. ECHO You must create it. EXIT /b 1 ) CALL :debug "Parms: %ctl% %cmd% %slot% %device% %drive%" IF "%cmd%" EQU "unload" GOTO :cmdUnload IF "%cmd%" EQU "load" GOTO :cmdLoad IF "%cmd%" EQU "list" GOTO :cmdList IF "%cmd%" EQU "loaded" GOTO :cmdLoaded IF "%cmd%" EQU "slots" GOTO :cmdSlots GOTO :cmdUnknown :cmdUnload CALL :debug "Doing disk -f %ctl% unload %slot% %device% %drive%" IF NOT EXIST %dirname%loaded%drive% ECHO 0 >%dirname%loaded%drive% FOR /f %%i IN ( %dirname%loaded%drive% ) DO SET ld=%%i IF "%slot%" EQU "%ld%" ( CALL :debug "Unloaded slot %ld% from drive %drive%" ECHO 0 >%dirname%loaded%drive% DEL %dirname%%device% >nul 2>nul SET rtn=0 ) ELSE ( ECHO Storage Element %slot% is Already Full CALL :debug "Storage Element %slot% is Already Full" SET rtn=1 ) GOTO :cmdExit :cmdLoad CALL :debug "Doing disk -f %ctl% load %slot% %device% %drive%" SET ld=0 IF NOT EXIST %dirname%loaded%drive% ECHO 0 >%dirname%loaded%drive% FOR /f %%i IN ( %dirname%loaded%drive% ) DO SET ld=%%i IF %ld% EQU 0 ( IF NOT EXIST %dirname%slot%slot% COPY nul %dirname%slot%slot% >nul DEL %device% fsutil hardlink create %device% %dirname%slot%slot% >nul 2>&1 SET rtn=%ERRORLEVEL% IF !rtn! EQU 0 ( ECHO %slot% >%dirname%loaded%drive% CALL :debug "Loaded slot %slot% into drive %drive%" ) ELSE ( CALL :debug "Create hardlink failed, return = !rtn!" ) ) ELSE ( ECHO Drive %drive% Full - Storage element %ld% loaded CALL :debug "Drive %drive% Full - Storage element %ld% loaded" ) GOTO :cmdExit :cmdList CALL :debug "Doing disk -f %ctl% -- to list volumes" IF EXIST %dirname%barcodes ( TYPE %dirname%barcodes ) ELSE ( FOR /l %%i IN ( 1, 1, %maxslot% ) DO ECHO %%i: ) SET rtn=0 GOTO :cmdExit :cmdLoaded CALL :debug "Doing disk -f %ctl% %drive% -- to find what is loaded" IF EXIST %dirname%loaded%drive% ( TYPE %dirname%loaded%drive% ) ELSE ECHO 0 SET rtn=0 GOTO :cmdExit :cmdSlots CALL :debug "Doing disk -f %ctl% -- to get count of slots" ECHO %maxslot% SET rtn=0 GOTO :cmdExit :cmdExit EXIT /b %rtn% :cmdUnknown ECHO '%cmd%' is an invalid command. GOTO :usage REM REM log whats done REM :debug IF NOT EXIST %dbgfile% GOTO :EOF FOR /f "usebackq tokens=2-4,5-7 delims=/:. " %%i IN ( '%DATE% %TIME%' ) do SET TIMESTAMP=%%k%%i%%j-%%l:%%m:%%n ECHO %TIMESTAMP% %* >> %dbgfile% GOTO :EOF