General Information
System Calls
Error Codes
Implementing Hooks

Backup Manager 3.0
Hooks

Contents

This document describes how Backup Manager can be extended by using system hooks.

Overview

Hooks allow the alteration of certain aspects of the key Backup Manager operations. This can be used to add features such as date/time-stamping backups as they're modified or restored, or compressing/decompressing backup files.

Types of hooks

Backup Manager has 10 different hooks. Each hook allows a routine to modify a particular operation. The following is a list of the hooks and an example of how each can be used:

Hook#OperationUsage example
1Creation of a new backup (just before the operation actually takes place) Compression of the backup file
2Creation of a new backup (just after the operation takes place) Addition of extended backup data as soon as the backup is created
3Updating of a backup Compression of the backup file
4Restoration of a backup or version Decompression of the backup file as it is restored
5Deletion of a backup Removal of data (created by an external hook or shell) specific to the backup being deleted
6Creation of a backup version Creation of any custom data related to the new version
7Changing of a version's comment Updating of any custom data related to the version
8Deletion of a version Removal of any custom data related to the version
9Occurrence of any error in an operation (before any action is taken by Backup Manager's error handler) Customization of error handler behavior
10Occurrence of an unknown (unexpected) error in an operation Handling of custom error codes for externally implemented features

Note: newbu is the only routine that has two hooks (#1 and #2) associated to it. Hook #1 is mainly used for modifying the backup file as it gets backed up. Hook #2 is mainly used for adding new data to the backup database for that backup. These two hook routines should be used as indicated here. During hook #1, it is too early to add backup information to the backup database, and during hook #2, it is too late to modify the backup file, because it has already been backed up.

Registering hook routines

A list named bhooks is used to register hooks with the Backup Manager system. The list contains a command to execute for each hook.

bhooks does not exist in a default installation, but it can be created by any program while the backup database is open. The list should have ten elements, all of them strings. Each element contains the code to execute for a particular hook. Elements representing unused hooks should be null strings.

To register a hook routine, the appropriate code simply has to be placed in the proper element in the bhooks variable. If you are writing a program that automatically installs a hook routine, it would be a good idea to check whether code already exists for the hook your program is going to install, and ask the user first if that code should be replaced. Depending on what the already installed hooks do, replacing a hook for another hook without the user's permission could cause bad things to happen.

Important: The database must be open (i.e., openbd must be called) before bhooks is modified.

Here's an example of a bhooks variable that calls the program myhook for hooks 1, 3, 4, and 6, with a parameter that indicates the hook number. (Such a parameter is not required, but allows the hook routine to know which operation is taking place.) All other hooks are currently unused; that is, they have no hook routines associated with them yet.

{"myhook(1)","","myhook(3)","myhook(4)","","myhook(6)","","","",""}

Communication with hook routines

The following variables are used for communication between hook routines and the Backup Manager system routines:

The specific data contained in the variables depends on the hook.

bhin

bhin is always a list. It contains information about the operation, usually the parameters passed to the system Backup Manager routine that is calling the hook routine.

Hook #Format
1LIST: {orig. path, act. path, bkup. file, 0, stored away?}
2LIST: {orig. path, act. path, bkup. file, bkup. index, stored away?}
3LIST: {orig. path, act. path, bkup. file, bkup. index}
4LIST: {orig. path, act. path, bkup. file, bkup. index, vers. index, overwrite?
5LIST: {orig. path, orig. path, bkup. file, bkup. index, delete stored-away?}
6LIST: {orig. path, act. path, bkup. file, bkup. index, vers. comment, vers. index}
7LIST: {orig. path, orig. path, bkup. file, bkup. index, vers. comment, vers. index}
8LIST: {orig. path, orig. path, bkup. file, bkup. index, vers. index}
9LIST: {error number, backup file path, display error dlg?, pass other errors?}
10LIST: {error number, backup file path, display error dlg?, pass other errors?

bhout and bhout2

bhout is used by hook routines to return data back to their calling routines. The bhout variable has different purposes depending on which hook routine is used.

Hook #Format
1STRING: Actual file
2Not used
3STRING: Actual file
4STRING: Actual file
5Not used
6STRING: Actual file
7STRING: Ver. comment to use
8Not used
9NUM: Value of errornum to assume
10NUM: Value of errornum to assume

bhout2 is used by some hooks to return additional data back to the calling program.

Hook #Format
1Not used
2Not used
3Not used
4Not used
5Not used
6STRING: Ver. comment to use
7Not used
8Not used
9STRING: Error message text
10STRING: Error message text

bhtemp

bhtemp is a reserved variable for hook routine use. Hook routines may use this variable for any purpose (for instance, to hold a temporary copy of a backup as it is being compressed). The bhtemp variable is automatically deleted the next time a hook routine is called, or when the backup database is closed.

Example: Hook routine for date/time stamping

This example shows how to write a hook routine that automatically records the last modification date and time for each backup in the backup database (for TI-89 AMS 2.08 or higher with hardware version 2). The date/time stamp is written each time a backup is created or modified.

The first step is to decide where the hook routine will be stored and what command will be used to execute it. For this example, the hook routine will be named hdtstamp and stored in the ωbman3 folder.

The second step is to write the hook routine. Since we are adding date/time stamps to modified or newly created backups, we want to have the date/time stamp added during hooks 2 (creation of a new backup) and 3 (updating of an existing backup).

So that we know which hook is taking place, we will have our routine take an input parameter (h) giving the number of the hook routine.

The code for the hook routine looks like this:

:hdtstamp(h)
:Prgm
:©Backup Manager 3 hook
:©Add date/time stamp to created/modified backup files
:
:©Check hook (only take action on hooks 2 and 3)
:If h=2 or h=3 Then
: ©Find the database field for date/time stamps
: ©If it's not defined, register it first
: Try
:  getbd("DTStamp","d")
: Else
:  regbd("DTSTamp","d")
: EndTry
:
: ©Add date/time stamp if AMS clock is on
: If isClkOn() Then
:  getDtStr()&" "&getTmStr()→#bfvar[bhin[4]]
: Else
:  "Unknown"→#bfvar[bhin[4]]
: EndIf
:EndIf
:
:EndPrgm

In order to activate the hook, it is now necessary to register it into the bhooks variable (from a program or the Home Screen):

:setFold(ωbman3)
:openbd()
:If getType(bhooks)≠"LIST" Then
:newList(10)→bhooks:Fill "",bhooks
:EndIf
:"hdtstamp(2)"→bhooks[2]
:"hdtstamp(3)"→bhooks[3]
:closebd()

Now, whenever a backup is created or updated and the AMS clock is turned on, the current date and time will be recorded for that backup and stored in the backup database. This can be verified by checking the extended backup data of the View Properties dialog in Advanced Shell.

Example: Hook routine to implement a custom error

This example shows how to use a hook routine to implement custom error codes.

Hooks #9 and #10 are used to hook into the error-handling system. The goal is to hook the handler of unrecognized error conditions and define a new error code.

Suppose we already have a hook installed that generates error code 15000 when there is not enough memory to perform an operation. This error is triggered with this code:

15000→errornum:PassErr

This error code is not recognized by the errh routine, so it will simply return the message "Unknown error 15000--probably a bug." To allow the Backup Manager system to recognize the error, we write the following hook routine hnewerr:

:hnewerr(h)
:Prgm
:©Backup Manager 3 hook
:©Define a custom error code
:
:©Catch hook 10
:If h=10 Then
: ©Check for error #15000
: If bhin[1]=15000 Then
:
:  ©Strip folder name from path, leaving just file name (there is not enough space in the error message for both)
:  Local file,start
:  inString(bhin[2],"\")→start
:  when(start>0,mid(bhin[2],start+1),bhin[2])→file
:  15000→bhout
:  "Not enough RAM to compress "&file→bhout2
: EndIf
:EndIf
:EndPrgm

Note that in our error message we include the name of the file where the error occurred, if available, but we strip off the folder name, leaving only the file name. Error text messages are limited to no more than 40 characters, so there is not enough room to show the entire path in this particular message. If a message of more than 40 characters is used, the error handler will crash with an AMS Dimension Error if it tries to display a dialog box for the error.

Now, we register the hnewerr hook (from a program or the Home Screen):

:setFold(ωbman3)
:openbd()
:If getType(bhooks)≠"LIST" Then
:newList(10)→bhooks:Fill "",bhooks
:EndIf
:"hnewerr(10)"→bhooks[10]
:closebd()

Now, when errh is called on an error, and errornum contains the value 15000, our custom error message will display.

One way to test this is by entering the following code on the Home Screen:

:setFold(ωbman3):openbd()
:Try:15000→errornum:PassErr
:Else:errh("foo\bar",true,false)
:EndTry
:closebd()

If all is well, a dialog should appear with the message "Not enough RAM to compress bar".