After a FileInstall
object is instantiated,
repeatedly invoking its
addEntry
method defines the files to be installed.
Each call to
addEntry
defines a single file to install (or uninstall).
addEntry
takes the following parameters:
std::ofstream
object
This parameter should be a reference to an empty, unopened,
std::ofstream
object.
If this call to
addEntry
defines a regular file (as defined by type
),
addEntry
will open this file object for writing.
The caller is responsible for writing the contents of the regular file into
the
std::ofstream
object, and closing it.
type
The type of the file being installed. The possible types are:
F
A regular file.
C
a
,
b
A character device, major device number
a
, minor device
b
.
B
a
,
b
A block device, major device number
a
, minor device
b
.
I
A FIFO file.
S
A socket file.
L
A symbolic link.
D
A directory.
d
Delete an existing file. This file type indicates that an existing file should be removed.
Most file types (where it makes sense to do so) may also be followed by a “b”, which marks a configuration file that might need backing up. Configuration files are marked for special processing. When uninstalling a package (which happens as part of a regular uninstall, or an upgrade to a newer version of the package) LPMtool checks if the contents of the file were changed. LPMtool keeps track of checksums of all installed files, and it checksums the file again before removing it. If the checksum is different, the file is not removed, but renamed as “filename.lpmsave.YYYYMMDD-HHMMSS”.
File types may also be followed by “n” to indicate that if the file already exists, it should not be overwritten, instead it's the new file that should get renamed.
username
The file's owner.
groupname
The file's group.
mode
The file's permissions.
filename
The full pathname to the file.
symlinktarget
If the file is a soft link, this is the soft link's target.
hardLinkedTo
If this is not an empty string, this indicates that the file is a hard link to an existing file.
All other parameters to
addEntry
must still be properly
set even if hardLinkedTo
is not an empty string.
If hardLinkedTo
is not located on the same
partition as filename
, or if it's not a regular
file, LPMtool will ignore hardLinkedTo
and install
the file as if hardLinkedTo
was an empty
string.
If the file is a regular file its contents will be automatically
copied by addEntry
.
addEntry
performs the following actions:
If the previous call to
addEntry
opened a temporary file,
addEntry
expects that temporary file to be closed
by now, so its buffers are flushed to disk (by using the
sync(2)
function).
The mount point of the partition that contains
filename
is identified.
In most cases
addEntry
creates a new file in
$MOUNTPOINT/.lpm
,
and this file
eventually becomes the file that's actually installed.
$MOUNTPOINT/.lpm
is a temporary directory where files are created, before they are installed
in their final location.
addEntry
uses a counter to create a new filename for the new file in
$MOUNTPOINT/.lpm
.
If
type
is not
“d”,
hardLinkedTo
is not empty,
that file exists and it's a regular file on the same filesystem as
filename
,
then $MOUNTPOINT/.lpm/COUNTER
is hard linked to the existing file,
and its buffers are flushed to disk.
If
type
is not
“d”,
hardLinkedTo
is not empty,
that file exists and it's a regular file on a different filesystem,
then the contents of
filename
are copied to
the new $MOUNTPOINT/.lpm/COUNTER
,
and its buffers are flushed.
In all other cases (except if the file type is “d”)
$MOUNTPOINT/.lpm/COUNTER
is created according to its filetype.
If it's a regular file, then the first argument to
addEntry
(),
std::ofstream
, is opened accordingly.
Otherwise $MOUNTPOINT/.lpm
's buffers
are flushed after the temporary file is created.
The file
/.lpm/manifest
is created, if it does not exist.
The file's type, its temporary name (COUNTER
),
username
,
groupname
,
mode
,
and filename
are appended to that file.
addEntry
()
returns the absolute pathname to the temporary file,
MOUNTPOINT/.lpm/COUNTER
,
unless type
is “d”
(in which case
addEntry
()
returns an empty string).
Package install/uninstall scripts (see Section 8, “Install/uninstall scripts”)
are added by the addScript
function.
This function is a wrapper for
addEntry
that passes the value s
for the type
parameter, which
addEntry
handles just like
“F” (plain file).
addEntry
creates a new file, whose contents become
the install/uninstall script to run.
The first line of the file will be
“#!interpreter
”
(see Section 8, “Install/uninstall scripts” for more information).
The
FileInstall
objects also provide a set of functions
that commit new records to a GDBM file.
These functions are invoked by
gdbm::ResourceDB's
commit()
function.
These functions end up writing special records to
/.lpm/manifest
.
Normally, each line in the manifest file names a single file to install
(or uninstall).
Four special records may also appear in this file, that correspond directly
to the same functions:
Open a GDBM file.
Store a record in the GDBM file, with the given key.
Remove a record from the GDBM file, with the given key.
Close the GDBM file.
An open record must be followed by zero or more store/remove records, followed
by a close record.
No other records may appear after the open record, and before the close
record.
This is enforced naturally.
gdbm::ResourceDB's
commit()
function calls the open method, the
insert/remove methods, and the close methods, in one shot, before
returning.