Random Access Backup | ||
---|---|---|
Prev |
This section discusses some of the RAB internals. This is only of any interest if you are planning to implement a new RAB client program. The real RAB functionality is implemented in a separate library. This isn't a general purpose library, the library only exists to achive a clear split between the user interface and the real functionality.
The library rablib is implemented as a shared library. To use the library in a RAB client program, you have to include the header file /usr/local/include/rablib.h. Most of the public functions in the rablib library are pretty high level, and do a lot of work when called. By design, a task is distributed to more than one single function only when the calling application needs to work with the user. For example, there isn't a single function that determines the files in need of a backup and does the backup since the application must inform the user to insert the backup medium. Hence, after computing our backup list, control is returned to the application, and the application is free to do anything necessary before calling the function performing the actual backup.
Moreover, the library calls some user provided callback functions at certain points while executing a library function. For example, when reading the RAB configuration files, the library calls a callback function for each configuration line which contains an error. Then the application is able to inform the user of this error in a way appropiate to this application. A command line program may simply write the error to the standard error output, while a graphical client can display the error in some status window. All callbacks recognized by a given function are collected in a structure. The calling application is free to use NULL as callback, and this means that there is no function to call. In fact, even the entire callback structure may be NULL, if no callback functions are provided. Each callback function returns an integer to the rablib library. Usually, this returned integer is zero, a value not equals zero commands the library to abort the current function as soon as possible. Then, the function will return an error value. You must not call any of the functions defined in the RAB library while executing a callback function.
A message function is a special callback function. These functions are called for each log message. The prototype is as follows.
Here, msg is the log message and level is its logging level. Note that the callback function gets all log messages, even the messages don't appearing in the log file.A similar concept are the progress functions. A progress function is a function called by the rablib library at more or less regular intervals. This can be used to display some kind of progress bar to the user, or to handle expose events in an X11 based program. A progress function has the following prototype.
The function in rablib calling our progress function is logically divided in phase_num phases, and is about to enter phase number phase. Similarly each phase consists of step_num steps, and we are going to start step number step. As with each callback function, you may also use NULL if no progress function is provided. The returned integer is handled analogously to the other callback functions.The main data type used by RAB is the opaque type RabInstance. You use exactly one instance of this type. A RabInstance is to rablib what a Display is to Xlib. Initially you will initialize a variable of type RabInstance, then use a pointer to this variable in your calls to the rablib library, and finally close the RabInstance variable via RabClose(). This final closing is mandantory, you really shouldn't terminate your application without this call. This yields the following schematic program structure.
#include <stdlib.h> #include <rablib.h> ... int main(int argc, char **argv) { RabInstance rab; int ret; ... if( (ret = RabOpen(&rab, ...)) < 0) { /* Error handling */ ... } ... RabClose(&rab); ... exit(0); } |
The functions used in this programs will be discussed later. In this example, you already see a common behaviour of our functions. Each function which may fail returns an status value of type int. The value zero means success and negative values are error conditions. All possible errors have a corresponding macro definition
#define RABERR_FOO (numeric value) |
in our header rablib.h. You are expected to use only these symbolic error values, and not the real numbers.
Rablib uses the following structure, defined in rablib.h, to describe the contents of the global configuration file /etc/rab.conf.
struct rab_config { int exclude_num; char **excludes; int excldir_num; char **excldir; int subdir_num; char **subdirs; int is_archive; int check_file; int check_days; int check_save; int check_complete; char *vardir; int libdir_num; char **libdir; char *builddir; char *isodir; char *dvd; char *cdwriter; char *logfile; int loglevel; int delete; int import; int interval; unsigned int only; unsigned int tarball; }; |
Almost all of the fields in this structure have the obvious meaning. The four check_X fields use the value -1 to mark the special none value. The field libdir is the list of all directories searched for shared libraries used with the exclude command. This is the complete list, i.e. the default directory /usr/local/lib/rab/lib is always included. The number of entries in the list is contained in the field libdir_num. Note that most of the default directory commands are simply listed as strings. The two fields only and tarball are set to one of the three macros RAB_BACKUP, RAB_CHECKPOINT or RAB_BOTH defined in rablib.h. If no value or none was specified, the corresponding field will be zero.
The RAB library uses some internal data files. These files are not documented in this manual, and you don't need to know anything about these files. But there is one exception to this rule. You will need the names of the data files in order to recover your current RAB configuration. Each backup directory contains copies of the global configuration rab.conf, and copies of the Directories and Media files. Moreover there are copies of all internal data files in each backup directory.
The rablib library contains the following global variables
extern char **rab_internal_names; extern int rab_internal_names_num; |
The first variable is a list of all names of our data files, and rab_internal_names_num is the length of this list. You must not modify any entry in this list.
Finally, the header rablib.h defines tree macros. First,
#define RABLIB_VERSION (numeric value) #define RABLIB_MINOR (numeric value) |
which expand to the major and minor version number, respectively, of this implementation of the rablib library. Second,
#define RAB_CD_MAX (numeric value) |
which gives the maximal number of CD's to be used for a single checkpoint.
We begin to discuss the functions provided by the RAB library.
This function is somewhat exceptional since it can't fail, and hasn't a RabInstance argument. The synopsis is as follows.
The three arguments have the following meaning.If version isn't NULL then we will write a pointer to a static string to *version. This string contains the version of the rablib library.
The maximal version number of shared libraries supported by this rablib version will be written to 'so_version unless so_version equals NULL. All numbers up to this value are supported.
If defaults isn't NULL, we will write the default configuration values to the structure defaults. All entries in this structure are read only.
Besides RabVersion() this is usually the first rablib function called in a program. This function performs the following actions.
Read the global configuration file, usually this means /etc/rab.conf.
Read the Media file. If a medium was removed since the last time a RAB program was executed, update our internal data files accordingly.
Read the Directories file. As above, process eventual changes in this file.
The RabOpen() function provides some callbacks, organized in the following auxiliary structure.
struct rab_open_cbs { int (*conf_cb)(int, char *, int, char *); int (*media_cb)(int, char *); int (*dir_cb)(int, char *); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
The callbacks msg_cb and progress are the message callback and the progress function, respectively. These were discussed above. The first callback conf_cb is called for each error in one of the RAB configuration files. The prototype is as follows.
The first argument file is one of the three constants RABCONF_GLOBAL, RABCONF_MEDIA, RABCONF_DIRECTORIES defined in rablib.h. It means that the error is in the global configuration file, in the Media file or in the Directories file, respectively. The second argument section is used in the RABCONF_DIRECTORIES case only. Then it is the name of the section containing the error. The final two arguments are the number of the errenous line, and the line itself.The second function media_cb is called to report on changes in the Media file. The callback has the following prototype.
The first argument typ describes the meaning of the following message string msg. It has one of the following symbolic values defined in rablib.h.A new medium was added to the Media file. The message string is the name of the new medium.
A medium was removed from Media. The message is the name of the removed medium.
The argument msg is the name of a directory in our Directories file, and this directory doesn't have any backup due to the removal of a backup medium.
We are ready to discuss the synopsis of RabOpen().
int RabOpen
(RabInstance *rab, struct rab_open_cbs *cb, char *conf, char *msg, int level, unsigned int flags);
The argument conf is the name of the global configuration file to use. The rablib library doesn't know about the default name /etc/rab.conf, so it is the responsibility of the client program to use this default. The conf path must be an absolute path. The other string argument msg is a log message to be written to the log file, if logging is enabled.
The very last argument flags is constructed by or'ing some of the following constants. All these constants are defined in rablib.h.
Debugging mode, don't write to any files. We will return an error if the Directories or the Media file was changed. This flag will be recognized by all rablib functions subsequently called.
Check only the configuration files. The rab variable will not be initialized. We will return a negative error code or the total number of errors in our configuration files.
The argument level is the logging level to be used instead of the value in the configuration file. If this flag isn't set, the argument level will be ignored.
Overwrite the import setting to on, and force the rablib library to rewrite it's internal data files on RabClose().
This flag is similar to RABOPEN_IMPORT_ON, but forces 'import off' instead of 'import on'.
Ignore all interval configuration commands in /var/lib/rab/Directories and in the global configuration file, respectively.
If the RabOpen() call was successfull, the function returns zero. Otherwise a negative error value is returned, and the RabInstance variable rab can't be used in subsequent calls. Normally, the calling program should report the error and exit. The complete list of all possible error values is as follows.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
A callback function returned a value distinct from zero.
Not enough memory available.
Can't open the global configuration file. The error code is in the errno variable.
The standard I/O library returned an error while reading the configuration file. The variable errno is set.
The configuration file contained a syntactic error.
Can't open the Media file. The error code is in the errno variable.
Like RABERR_READ_GLOBAL.
Like RABERR_CONF_GLOBAL.
These are analogous to the corresponding RABERR_X_MEDIA errors.
Can't open or read one of the internal RAB data files. The name of the affected file is in the log file.
Can't open the logfile for writing. The concrete error code is in the errno variable.
Can't load all external exclude functions. Details are in the log file.
One of the internal RAB data files is damaged. Again, details are in the log file. This really shouldn't happen.
Either the Directories file does not exist or it contains no toplevel sections. In any case, there is nothing to do, and we will not create a RabInstance structure. However, this isn't really an error, but just an unusual state.
The conf argument is not an absolute path.
Each RabInstance variable initialized with RabOpen() must be closed with RabClose(). This frees all allocated memory and finishes all internal data files. This call isn't optional, don't simply exit() the program.
The synopsis is as follows.
The argument rab is the address of a RabInstance variable initialized by RabOpen(). You shouldn't use this variable anymore after calling RabClose().This function frees all memory allocated by a RabInstance structure initialized with RabOpen(). But unlike RabClose(), we don't rewrite our internal data files. This function is usually used to abort RAB after one of our functions returned an error.
The synopsis is as follows.
The argument rab is the address of a RabInstance variable initialized by RabOpen(). You shouldn't use this variable anymore after calling RabAbort().The synopsis is
The argument rab is an initialized RabInstance variable. We will write the global configuration information to config. The contents of config must not be modified in any way.We use the following structure to gather data about a backup.
struct rab_backup_list { int dir_num; char **dir; int *archive; int *checkpoint; int files; int blocks; int is_link; char *medium; RabBackupList private; }; |
With the exception of checkpoint, you must not modify any of the values in this structure. The fields in the rab_backup_list structure have the following meaning.
This is the total number of directories chosen for a backup. This includes the checkpoint directories.
Given any index i between zero and dir_num, the string dir[i] is the name of the 'i'th directory in the backup list.
For each i as above, the number archive[i] is true, i.e. not zero, if the 'i'th directory is an archive directory.
For each i as above, the value of checkpoint[i] is zero if no checkpoint of directory i is planned, otherwise the value equals 1. Before passing the rab_backup_list structure to RabComputeCheckpoint(), you may change these values to schedule other directories for a checkpoint, or to reject a pending checkpoint for some directories, respectively.
These fields are for informational purposes only. The field files is the number of changed or new files in the directory. The field blocks is the total number of blocks used for this backup.
The field is_link will be distinct from zero if the medium chosen for backup corresponds to an ordinary directory specified with a LINK line in /var/lib/rab/Media.
This is the name of the medium in the Media file chosen for the next backup. When no files are to be copied to the DVD RAM, this field has the value NULL.
This field is for internal use by the rablib library. The type RabBackupList is an opaque type, not of any use to a rablib client program.
Like RabOpen(), the RabComputeBackup() function supports various callbacks, which are collected in the following structure.
struct rab_get_list_cbs { int (*dir_cb)(int, char *); int (*file_cb)(int, char *, char *); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
The fields msg_cb and progress are a message callback and a progress function, respectively, as discussed above. The callback function
is called for each directory to be examined for backup. The dir is the name of this directory. If dir is the toplevel directory of a directory tree, then ind is the index of this directory tree in the argument list given to RabComputeBackup(). Otherwise, ind equals the negative constant RAB_SUBDIR defined in rablib.h. Similarly, the callback is called for each changed file. The first argument change specifies how the file was changed. The value of change is one of the following constants defined in rablib.h.The file was modified.
The file is newly created.
The file was removed since our last visit in this directory.
The function RabComputeBackup() uses the following synopsis.
int RabComputeBackup
(RabInstance *rab, char **dirs, int *force, int dir_num, char *medium, struct rab_get_list_cbs *cb, struct rab_backup_list *ret);
You can't call RabComputeBackup() on a directory tree already initialized with either the RabComputeBackup() function or the RabPrepareCheckpoint() function described below. This isn't allowed even if the function in question failed on this directory.
If successfull, RabComputeBackup() returns zero. Otherwise a negative error value is returned. The possible errors are listed below.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
Either one of the specified directories isn't defined in the Directories file, or you passed an empty list to RabComputeBackup().
One of the local per directory configuration files contained an error. This means an error either in a local directories file or in a local exclude file, respectively. Details are written to the log file.
A callback function returned a value distinct from zero.
Not enough memory available.
Counldn't read a directory. Details are written to the log file, and errno is set.
Counldn't get the modification time of a file. As above, details are written to the log file and errno is set.
Could not find a usable backup medium. Usually, this means the Media file does not exist or is empty. This error will also be returned if a non existing backup medium was specified in this call to RabComputeBackup().
One of the requested directory trees was already processed with either the RabComputeBackup() function or the RabPrepareCheckpoint() function, respectively.
RAB failed to create some tarball. Details will be written to the logfile.
As already mentioned, you may want to change the checkpoint field of an initialized rab_backup_list structure. Unfortunately, the entries in the checkpoint array are not indexed like the dirs argument originally passed to either RabComputeBackup() or RabPrepareCheckpoint(). The rablib library provides two functions to convert between these two numberings.
The first of these two functions is
to convert the original index ind used with an argument list to the corresponding index in the checkpoint array. If there does not exists a corresponding index, RabListIndex() returns the negative error value RABERR_ARGUMENT.The second function converts indizes in the opposite direction, i.e. from an index used in the checkpoint array to an original argument index.
If ind is out of bounds, RabOriginalIndex() returns the negative error value RABERR_ARGUMENT.The function
is an auxiliary function used to read the list of all backup directories defined in the Directories file. The first argument, rab, is the usual pointer to a RabInstance variable initialized via RabOpen().If successfull, the function returns zero and writes the directory list to the variable pointed to by pdirs. The length of this list is written to *pdir_num. You must free the returned list with the free(3) function defined in stdlib.h. The only possible error value is RABERR_MEMORY if not enough memory is available.
The RabBackup() function is used to really make the backup to a DVD RAM medium. The function supports a callback structure similar to the structure used by the RabComputeBackup() function.
struct rab_backup_cbs { int (*dir_cb)(int, char *); int (*file_cb)(char *, char *); int (*sync_cb)(void); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
The fields dir_cb, msg_cb and progress are exactly like the corresponding fields in the rab_get_list_cbs structure. The file_cb function is also similar to the same field in rab_get_list_cbs, only the first argument is omitted, i.e. the synopsis is
This function is called for each copied file.After writing all files to the DVD RAM, the rablib library will sync the DVD RAM device. The callback
is called just before the call to sync(2) happens.RabBackup() is defined by the following prototype.
The rab argument is as usual. The second argument, backup is the adress of a structure variable of type rab_backup_list which was initialized by the RabComputeBackup() function. RabBackup() may modify this structure. In particular, additional directories may be scheduled for a checkpoint if there was not enough space on the DVD RAM. Finally, the last argument specifies the callbacks to use.You can't call RabBackup() on a directory tree already used as an argument to either RabBackup() or RabComputeCheckpoint(:).
Like almost all of our functions, RabBackup() returns zero if successfull. The possible error codes are as follows.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
A callback function returned a value distinct from zero.
Not enough memory available.
The backup structure isn't correctly initialized. This usually means an error in the calling program.
An error occured while reading a file. The errno variable is set.
An error occured while writing a file to the DVD RAM. As above, errno is set.
RAB failed to open a file for reading or writing. Details are in the log file, and errno is set.
Failed to create a new directory on the DVD RAM. The errno variable is set.
As already mentioned, we will use the current date as the name of the new backup directory. If the current backup is either the second, third or whatever backup of this day, we will append a lowercase letter to the current data. The error value RABERR_NOSLOT means that there isn't another lowercase letter available.
However, if you really want to make more than 27 backups per day, RAB probably isn't the right tool for this job.
The sync(2) function returned an error, errno is set.
This is a somewhat exceptional error value. The backup was almost sucessfull, but there was not enough space on the DVD RAM to save all directories. The remaining directories will be added to the checkpoint list in the backup argument. The calling application really should produce a checkpoint.
Can't mount the DVD RAM medium or the medium wasn't correctly initialized for use by RAB. Details are written to the log file.
Failed to write one of our internal data files. Details are in the log file.
One of the directories trees in backup was already used for a call to RabBackup() or RabComputeCheckpoint(), respectively.
RAB failed to create some tarball. Details will be written to the logfile.
Like the rab_backup_list structure, the following structure is used to control a checkpoint.
struct rab_checkpoint_list { int dir_num; char **dir; int *archive; int files; int blocks; int cds; RabCheckpointList private; }; |
All the fields with a name already present in the rab_backup_list structure, have the same meaning, too. The type RabCheckpointList is another opaque type used internally by the rablib library. The new field cds is the number of CD's needed for this checkpoint.
The RabComputeCheckpoint() provides the following checkpoints.
struct rab_compute_checkpoint_cbs { int (*scan_cb)(char *); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
The msg_cb and progress entries are the usual message callback and progress functions, respectively.
In order to fill unused space on the last CD of a checkpoint, the RabComputeCheckpoint() function may check further directories listed in the Directories file. When examing such a directory, the callback
will be called with the name of the directory as its argument.Finally, the synopsis of our RabComputeCheckpoint() function is as follows.
int RabComputeCheckpoint
(RabInstance *rab, struct rab_backup_list *backup, struct rab_checkpoint_list
*checkpoint, struct rab_compute_checkpoint_cbs
*cb, unsigned int flags);
The flags argument shall be either 0 or the constant RAB_NO_TREEADD defined in rablib.h. In the latter case, RAB will not try to add other directory trees to fill a checkpoint CD. However, directories specified in a call to RabAddCDDirectories() will still be added.
The original rab_backup_list structure backup will be destroyed. You can't use this structure anymore after calling RabComputeCheckpoint(), even if RabComputeCheckpoint() failed. Moreover, the backup argument must not contain any directory tree already passed to RabComputeCheckpoint().
The function returns zero if successfull and a negative error code otherwise. The following error codes are possible.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
A callback function returned a value distinct from zero.
Not enough memory available.
The backup argument isn't correctly initialized. This usually means an error in the calling program.
An error occured while looking for other directories to be added to the checkpoint. You may continue the checkpoint, anyway.
One of the directory trees in backup was already processed by RabComputeCheckpoint().
More than RAB_CD_MAX CD's needed to perform this checkpoint.
The function computed the checkpoint sucessfully, but we had to omit some files larger then 600 MB. Details about these files are in the log file. The calling application should notify the user, and may normally continue.
RAB failed to create some tarball. Details will be written to the logfile.
In order to initialize our rab_checkpoint_list structure with RabComputeCheckpoint(), we need an already initialized rab_backup_list structure. Sometimes, you may wish to create a checkpoint without a prior backup, hence you shouldn't use the RabComputeBackup() function. In these cases, the function RapPrepareCheckpoint() is used to initialize the rab_backup_list structure. Note that you can't use this structure as an argument to RabBackup().
The callback structure is similar to the one used by the RabComputeBackup() function. The file_cb is missing since this wouldn't make much sense for the RabPrepareCheckpoint() function.
struct rab_prepare_checkpoint_cbs { int (*dir_cb)(int, char *); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
All of this fields are equivalent with the corresponding fields in the rab_compute_backup_cbs structure.
The synopsis is as follows.
int RabPrepareCheckpoint
(RabInstance *rab, char **dirs, int dir_num, struct rab_prepare_checkpoint_cbs
*cb, struct rab_backup_list
*ret);
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
Either one of the specified directories isn't defined in the Directories file, or you passed an empty list to RabComputeBackup().
One of the local per directory configuration files contained an error. This means an error either in a local directories file or in a local exclude file, respectively. Details are written to the log file.
A callback function returned a value distinct from zero.
Not enough memory available.
Counldn't read a directory. Details are written to the log file, and errno is set.
Counldn't get the modification time of a file. As above, details are written to the log file and errno is set.
One of the requested directory trees was already processed with either the RabComputeBackup() function or the RabPrepareCheckpoint() function, respectively.
RAB failed to create some tarball. Details will be written to the logfile.
Usually, there will be some unused space left on a RAB backup CD. The function RabAddCDDirectories() will be called with a list of directories intended to fill this unused space. Of course, there is no guarantee that any of these directories is actually written to a CD. The rablib library will use a callback function to inform the calling application about anything related to these additional directories. This callback uses the following synopsis.
The argument ind is the index of the directory this function call refers to in the list originally passed to RabAddCDDirectories(), and dir is this directory path itself. The first argument what defines the event reported by this call to filldir_cb(). As usual, the callback filldir_cb() returns a value distinct from zero to cancel the running checkpoint.The parameter what equals one of the following constants defined in rablib.h.
RAB is about to scan the contents of directory dir.
An error occured while reading the specified directory tree. Details will be written to the logfile, and the directory will be ignored in the sequel.
RAB begins to write direcory dir to a CD.
An error occured while writing the specified directory tree to CD. Details will be written to the logfile, and the directory will be ignored in the sequel.
Directory dir was completely written to a CD.
We use the following prototype.
int RabAddCDDirectories
(RabInstance *rab, struct rab_checkpoint_list
*checkpoint, char **dirs, int dir_num, int (*cb)(int,
int, char *));
RabAddCDDirectories() returns zero on success and one of the following negative error values otherwise.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
Either one of the listed directories is not an absolute path or RabAddCDDirectories() was already called for checkpoint. At most one call to RabAddCDDirectories() is possible for each rab_checkpoint_list structure.
Not enough memory available.
The checkpoint parameter was already used as an argument to RabCheckpoint().
The function RabCheckpoint() creates the real checkpoint. We will use the following callbacks.
struct rab_checkpoint_cbs { int (*dir_cb)(int, char *); int (*run_cb)(int, void *); int (*insert_cb)(int, int, int); int (*msg_cb)(int, char *); int (*progress)(int, int, int, int); }; |
The callbacks msg_cb and progress are the usual message callback and progress function, respectively. The function
is similar to the corresponding callback used by the RabBackup() function. The string dir is the name of the directory which is going to be saved. The first argument ind is the index of this directory in the list originally used to create our rab_backup_list structure if dir is the toplevel directory of a directory tree. This list was an argument to either the RabComputeBackup() function or to the RabPrepareCheckpoint() function. If the directory tree in question was not passed as an argument to one of these functions, but was selected internally by RAB to fill some space on a CD, we will pass the negative constant RAB_ADDED_DIRECTORY as ind. If dir is not a toplevel directory, but just some subdirectory, we will pass the negative constant RAB_SUBDIR for ind.The second callback
will be called either if RAB is about to run an external command, or if such a command just terminated successfully. The argument what is one of the following constants defined in rablib.h. The second argument detail gives more details depending on the value of what.RAB is about to run mkisofs.sh. The detail argument is a pointer to a rab_mkisofs_detail structure defined in rablib.h.
struct rab_mkisofs_detail { char *image_dir; unsigned int blocks; }; |
mkisofs.sh terminated successfully. The detail argument points to a rab_path_detail structure describing the ISO9660 image file mkisofs.sh created. This structure is defined in rablib.h.
struct rab_path_detail { char *directory; char *file; }; |
RAB is about to run cdrecord.sh. The argument detail is again a pointer to a rab_path_detail structure holding the name of the ISO9660 image file going to be written by cdrecord.sh.
cdrecord.sh terminated successfully. Now, detail is NULL.
The remaining callback
is called each time RAB is going to write an image file to a CD. The application is expected to notify the user to insert a new blank CD-R. The first agument cd is the number of this CD in the checkpoint currently running, and cd_num is the total number of CD's used in this checkpoint. The final argument count usually equals zero, unless the RAB library already tried to burn the current image file but cdrecord(1) failed. In this case, count counts the number of attempts to write this image file.Insert_cb shall return one of the following constants defined in rablib.h.
The user inserted a CD-R, as requested.
Stop the running checkpoint but continue with the current program. RAB will pretend the canceled checkpoint never happened.
Cancel the current rablib instance. RabCheckpoint() will return an error value of RABERR_CANCELED.
Don't burn the ISO9660 image file, but assume this already happened. In particular, run_cb(RAB_SUCCESS_CDRECORD, NULL) will be called.
We use the following prototype
int RabCheckpoint
(RabInstance *rab, struct rab_checkpoint_list
*checkpoint, struct rab_checkpoint_cbs
*cb);
The rab_checkpoint_list structure was initialized by the RabComputeCheckpoint() function. As with our other functions, no directory tree present in checkpoint must be an argument to RabCheckpoint() before.
The following negative error values are possible.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
A callback function returned a value distinct from zero.
The checkpoint or the cb argument isn't correctly initialized. Recall that there must be an insert_cb callback present.
An error occured while reading a file. The errno variable is set.
An error occured while writing the backup directory tree. More detailed error messages are in the logfile.
The mkisofs(8) command returned an error.
Couldn't remove the backup directory or an ISO image file. RAB continues the checkpoint, anyway. You should notify the user to take care of remaining backup files.
The cdrecord(1) command returned an error.
One of the directory trees in checkpoint was already used in a call to RabCheckpoint().
Not enough space left to write either our image directory tree or the ISO9660 image file.
RAB failed to create some tarball. Details will be written to the logfile.
Each rab_backup_list structure initialized by either the RabComputeBackup() function or by the RabPrepareCheckpoint() function, and not used as an argument to RabComputeCheckpoint(), should be freed via RabFreeBackup() when done with this structure.
The exact synopsis is
The argument rab is the RabInstance variable originally used to initialize the rab_backup_list structure backup.This function is similar to RabFreeBackup(), and is used to free a rab_checkpoint_list structure initialized by RabComputeCheckpoint(). The synopsis is
The parameters have the same meaning as with the RabFreeBackup() function.The RabLookup function is used to search for all backups of a given file. The file may be deleted on disk. A backup is described by the following structure defined in our header rablib.h.
struct rab_backup_record { int checkpoint; char *medium; int day; int month; int year; }; |
Obviously, the last three fields day, month and year describe the date of this backup. The fields day and month are counted beginning with one. The first field checkpoint is distinct from zero if this backup is a checkpoint, and in this case medium equals NULL. Otherwise, medium is the name of the DVD RAM used for this backup.
Additional information about the file in question will be returned using the following structure
struct rab_backup_info { char *tree; int removed; int backup; int b_day; int b_month; int b_year; int checkpoint; int c_day; int c_month; int c_year; }; |
The first field, tree, is a string giving the directory tree this file is in. This is a read-only value, you must not modify tree in any way. The second value removed will be distinct from zero if the file was removed on disk. If there currently exists a backup of the file, then the field backup will be distinct from zero and the next three members define the date of the most current backup of the file. The remaining four fields are similar and apply to checkpoints instead of backups.
We are using the following synopsis.
int RabLookup
(RabInstance *rab, char *file, struct rab_backup_record
**record, int *record_num, struct rab_backup_info *info);
The next two variables are used to return all backup records found. If record is not NULL, then it points to a pointer to a rab_backup_record structure and record_num points to an integer. If successfull, we will store a pointer to a list of structures describing all backups of the given file in *record. The length of this list is written to *record_num. If there is no backup of the file, we will simply write NULL to record and 0 to record_num. You are responsible to free the returned list via the RabFreeRecord() function discussed below.
If the final argument info is distinct from NULL and there exists an entry for the given file in our internal database, then we will initialize the structure pointed to by info with information about file.
The following negative error values may be returned from the RabLookup() function.
An internal error occured. This shouldn't happen, and indicates an error in the rablib library.
Either the file argument is not an absolute path, or it contains unexpected components.
Not enough memory available.
An error occured while reading our backup database. The errno variable is set.
One of the internal RAB data files is damaged. Details are in the log file. This really shouldn't happen.
The file file does not exist in our database.
This functions free a list of backup records returned by RabLookup(). The synopsis is as follows.
The arguments record and record_num were returned by an earlier call to RabLookup().This function is used to create a human readable string out of a RAB error value RABERR_X. Optionally, you may pass the value of the errno variable. The synopsis is as follows.
The function returns a pointer to a static array which must not be modified. The next call to the RabError() will overwrite the contents of this array.The first parameter rab_error is the RABERR_X error value. The second argument use_errno is one of the following three constants defined in the rablib.h header.
There isn't an errno value available.
Use the current value of the errno variable to form an error string.
The function expects a third argument of type int, and the value of this argument is the errno variable to use. Usually, this is a saved errno variable.
This function is similar to the standard C function perror(3), but we will get an explicit argument describing the error code. The synopsis is as follows.
We will print an error message on the standard error output, terminated by a newline character and containing the specified argument text.The functions, variables, structures and macros discussed in this section are the only symbols expected to be used by any RAB client program. Of course, the RAB library librablib.so exports also a number of symbols to be used internally by librablib.so. Moreover, the header file rablib.h defines additional macros and types. To avoid collisions with names used in an application program, RAB uses the following naming conventions for it's internal names.
Function names start with the prefix Rab__.
Externally visible variable names start with the prefix rab__.
Internal macros defined in rablib.h start with the prefix RAB__.
Internal structure names defined in rablib.h start with the prefix rab__.
Internal type names defined in rablib.h start with the prefix Rab__.