WARNING: The following chapter is big and is a little
bit hard to read.
The prototype file is essentially important for the packaging process, as it defines _how_ the files should be included in your package.
In our example, it would look like this:
$ cd <temporarily installation root> $ pkgproto * | sort d none bin 0755 root other d none info 0755 root other d none man 0755 root other d none man/man1 0755 root other f none bin/bc 0755 root other f none bin/dc 0755 root other f none info/bc.info 0644 root other f none info/dc.info 0644 root other f none man/man1/bc.1 0644 root other f none man/man1/dc.1 0644 root other
The syntax is:
<type> <class> <name of file> <permissions> <user> <group>
|b||block special device (usually a file system)|
|c||character special device (usually a raw disk device)|
|e||editable file (will be usually edited during install)|
|p||named pipe (FIFO)|
|v||volatile file (file to be created which changes size later -> logfiles)|
|x||directory only accessible for this package|
$ man -s4 prototype
The include directive means that the specified file will be treated as a file vital to the package. The usual Options are:
i depend(=<path to dependancy file>)
This tells us, where the dependancy file is located. The syntax of depend is:
P ARbash Bourne Again Shell - 2.05a
<type> <pkg name> <full pkg name>
For the installation of our binary calculator this means that we would have
ARbash first installed before we can install our ARbc package.
Types of dependancies are:
|P||Prerequisite (required package)|
|I||Incompatible PKG (actual package to be installed cannot be installed due to incompatibilities to the named package)|
|R||Reverse Dependancy (tells us that the package currently being installed is a pre-requisite dependancy to another package)|
i pkginfo(=<path to pkginfo file>)
Defines, where to look for the _required_ pkginfo file.
i version(=<path to version file>)
Tells "pkgmk" where to look for a version file. This is optional/ informational.
i preinstall(=<path to preinstall script>)
Tells "pkgmk" where to look for a script to be executed _before_ the package will be installed, e.g. to create application specific users.
i preremove(=<path to preremove script>)
Tells "pkgmk" where to look for a script to be executed _before_ the package will be removed, e.g. to stop a webserver.
i postinstall(=<path to postinstall script>)
Tells "pkgmk" where to look for a script to be executed _after_ the package has been installed, e.g. start a webserver with a default config.
i postremove(=<path to postremove script>)
Tells "pkgmk" where to look for a script to be executed _after_ the package has been removed, e.g. cleaning up some old temporary files.
i request(=<path to request script>)
Tells "pkgmk" where to look for a script which asks the user for certain information, e.g. license key.
i checkinstall(=<path to checkinstall script>)
Tells "pkgmk" where to look for a script which gathers installation data
The sequence of these scripts during package installation is:
|2.||execute request script and ask user|
|3.||execute checkinstall script and gather data|
Additionally, there are the following directives:
This means that the following string is a shell command, e.g. means
the binary path to be set.
! search <dir1> <dir2> <dir3> ...
This means that within the following directories the files to be packaged will be searched in.
! include <dir>
This means that another prototype will be included in the mentioned directory.
! default <attributes>
This means that a list of default parameters like mode, owner and group will be defined, but they are required and not defined in the prototype file.
Now that we got all the files, we have to modify the newly created prototype file. First of all, save it to your temporarily installation root:
$ cd <temporarily installation root> $ pkgproto * | sort > prototype
The only one absolutely _required_ file we have to add is the pkginfo file. So open the newly created prototype file with your favourite editor and add a
i pkginfo=<name/location of pkginfo file>
to the file. Assuming the pkinfo file is located in the same directory as the prototype file, a simple
also does the job. Now we need to change the location of the files. Just do the second compilation and installation run with the final location. Then we modify our prototype file to this:
i pkginfo=pkginfo d none usr ? ? ? d none usr/local ? ? ? d none usr/local/bin ? ? ? d none usr/local/info ? ? ? d none usr/local/man ? ? ? d none usr/local/man/man1 ? ? ? f none usr/local/bin/bc 0755 bin bin f none usr/local/bin/dc 0755 bin bin f none usr/local/info/bc.info 0644 bin bin f none usr/local/info/dc.info 0644 bin bin f none usr/local/man/man1/bc.1 0644 bin bin f none usr/local/man/man1/dc.1 0644 bin bin
In the former document about the pkginfo file, the variable BASEDIR defines
the packaging - and later the installation root - to be "/", but
our files are located somewhere else. The only solution to come
around this problem is to do two compilation runs (you remember, I told you
in the introduction). The first run for catching all files in a temporarily
install location, the second for the final installation path.
Although bc does really not need a bootskript as it is no daemon, we will include a dummy bootscript called bc_startup.sh, just as an example. But how will we be able to build a system PKG if we can't become superuser to copy the bootskript to /etc/init.d and create a symbolic link to /etc/rc3.d? The answer is quite simple. Within the prototype file we can work with include paths and symbolic links. Assuming our boot script is in the same directory as our pkginfo and prototype file, we simply add the following line to the prototype file:
f none etc/init.d/bc_startup=bc_startup 0755 root other
"pkgmk" will add our local bc_startup.sh to the package as it would reside in /etc/init.d/bc_startup. Finally we add another entry to the prototype file:
s none etc/rc3.d/S99bc_startup=../init.d/bc_startup
This will create a symbolic link from the central init skript directory in
/etc/init.d to /etc/rc3.d/S99bc_startup
The syntax for these include paths is:
<destination path>=<source path>
IMPORTANT NOTE: When adding a symbolic link, the file that the
link refers to _HAS_ to be listed first! As a consequence it is the best
solution to put all symbolic links at the end of the prototype file.
Additionally, you will have noticed in the prototype file above that I listed
the complete /usr/local directory structure and added "?" at the
end of the line. Why that?
... for script in <current runlevel>*.sh do . $script done ...
Bootscripts not ending with ".sh" are treated as shell skripts and are therefore executed. (If you are interested in, where in the init bootprocess
this happens, take a look at /sbin/rcS and search for a similar text block:
... if [ -d /etc/rcS.d ]; then for f in /etc/rcS.d/S*; do if [ -s $f ]; then case $f in *.sh) . $f ;; *) /sbin/sh $f start ;; esac fi done fi ...
Finally: So our final prototype file will look like:
i pkginfo=pkginfo d none usr ? ? ? d none usr/local ? ? ? d none usr/local/bin ? ? ? d none usr/local/info ? ? ? d none usr/local/man ? ? ? d none usr/local/man/man1 ? ? ? f none usr/local/bin/bc 0755 bin bin f none usr/local/bin/dc 0755 bin bin f none usr/local/info/bc.info 0644 bin bin f none usr/local/info/dc.info 0644 bin bin f none usr/local/man/man1/bc.1 0644 bin bin f none usr/local/man/man1/dc.1 0644 bin bin f none etc/init.d/bc_startup=bc_startup 0755 root other s none etc/rc3.d/S99bc_startup=../init.d/bc_startup