7.6. Expanding Package List with Keywords

All keywords can also take optional arguments in parentheses. The arguments are owner, group, and mode. This argument is used on the file or directory referenced. To change the owner, group, and mode of a configuration file, use:

@sample(games,games,640) etc/config.sample

The arguments are optional. If only the group and mode need to be changed, use:

@sample(,games,660) etc/config.sample

7.6.1. @fc directory

Add a @dir entry for the directory passed as an argument, and run fc-cache -s on that directory after installation and deinstallation.

7.6.2. @fcfontsdir directory

Add a @dir entry for the directory passed as an argument, and run fc-cache -s, mkfontscale and mkfontdir on that directory after installation and deinstallation. Additionally, on deinstallation, it removes the fonts.scale and fonts.dir cache files if they are empty.

7.6.3. @fontsdir directory

Add a @dir entry for the directory passed as an argument, and run mkfontscale and mkfontdir on that directory after installation and deinstallation. Additionally, on deinstallation, it removes the fonts.scale and fonts.dir cache files if they are empty.

7.6.4. @info file

Add the file passed as argument to the plist, and updates the info document index on installation and deinstallation. Additionally, it removes the index if empty on deinstallation.

7.6.5. @sample file

Add the file passed as argument to the plist.

On installation, check for a real file with just the base name (the name without the .sample extension). If the real file is not found, copy the sample file to the base file name. On deinstallation, remove the configuration file if it has not been modified. See Section 7.3, “Configuration Files” for more information.

7.6.6. @shell file

Add the file passed as argument to the plist.

On installation, add the full path to file to /etc/shells, while making sure it is not added twice. On deinstallation, remove it from /etc/shells.

7.6.7. Base Keywords

There are a few keywords that are hardcoded, and documented in pkg-create(8). For the sake of completeness, they are also documented here.

7.6.7.1. @ [file]

The empty keyword is a placeholder to use when the file's owner, group, or mode need to be changed. For example, to set the group of the file to games and add the setgid bit, add:

@(,games,2755) sbin/daemon

7.6.7.2. @cwd [directory] (Deprecated)

Set the internal directory pointer to point to directory. All subsequent filenames are assumed relative to this directory.

7.6.7.3. @exec command

Execute command as part of the unpacking process. If command contains any of these sequences somewhere in it, they are expanded inline. For these examples, assume that @cwd is set to /usr/local and the last extracted file was bin/emacs.

%F

Expand to the last filename extracted (as specified). In the example case bin/emacs.

%D

Expand to the current directory prefix, as set with @cwd. In the example case /usr/local.

%B

Expand to the basename of the fully qualified filename, that is, the current directory prefix plus the last filespec, minus the trailing filename. In the example case, that would be /usr/local/bin.

%f

Expand to the filename part of the fully qualified name, or the converse of %B. In the example case, emacs.

7.6.7.4. @unexec command

Execute command as part of the deinstallation process. Expansion of special % sequences is the same as for @exec. This command is not executed during the package add, as @exec is, but rather when the package is deleted. This is useful for deleting links and other ancillary files that were created as a result of adding the package, but not directly known to the package's table of contents (and hence not automatically removable).

7.6.7.5. @mode mode

Set default permission for all subsequently extracted files to mode. Format is the same as that used by chmod(1). Use without an arg to set back to default permissions (mode of the file while being packed).

Important:

This must be a numeric mode, like 644, 4755, or 600. It cannnot be a relative mode like u+s.

7.6.7.6. @owner user

Set default ownership for all subsequent files to user. Use without an argument to set back to default ownership (root).

7.6.7.7. @group group

Set default group ownership for all subsequent files to group. Use without an arg to set back to default group ownership (wheel).

7.6.7.8. @comment string

This line is ignored when packing.

7.6.7.9. @dir directory

Declare directory name. By default, directories created under PREFIX by a package installation are automatically removed. Use this when an empty directory under PREFIX needs to be created, or when the directory needs to have non default owner, group, or mode. Directories outside of PREFIX need to be registered. For example, /var/db/${PORTNAME} needs to have a @dir entry whereas ${PREFIX}/share/${PORTNAME} does not if it contains files or uses the default owner, group, and mode.

7.6.7.10. @dirrm directory (Deprecated)

Declare directory name to be deleted at deinstall time. By default, directories created under PREFIX by a package installation are deleted when the package is deinstalled.

7.6.7.11. @dirrmtry directory (Deprecated)

Declare directory name to be removed, as for @dirrm, but does not issue a warning if the directory cannot be removed.

7.6.8. Creating New Keywords

Package list files can be extended by keywords that are defined in the ${PORTSDIR}/Keywords directory. The settings for each keyword are stored in a UCL file named keyword.ucl. The file must contain at least one of the next sections:

attributes

Changes the owner, group, or mode used by the keyword. Contains an associative array where the possible keys are owner, group, and mode. The values are, respectively, a user name, a group name, and a file mode. For example:

attributes: { owner: "games", group: "games", mode: 0555 }
action

Defines what happens to the keyword's parameter. Contains an array where the possible values are:

setprefix

Set the prefix for the next plist entries.

dir

Register a directory to be created on install and removed on deinstall.

dirrm

Register a directory to be deleted on deinstall. Deprecated.

dirrmtry

Register a directory to try and deleted on deinstall. Deprecated.

file

Register a file.

setmode

Set the mode for the next plist entries.

setowner

Set the owner for the next plist entries.

setgroup

Set the group for the next plist entries.

comment

Does not do anything, equivalent to not entering an action section.

ignore_next

Ignore the next entry in the plist.

pre-install, post-install, pre-deinstall, post-deinstall, pre-upgrade, post-upgrade

These keywords contains a sh(1) script to be executed before or after installation, deinstallation, or upgrade of the package. In addition to the usual @exec %foo placeholders described in Section 7.6.7.3, “@exec command, there is a new one, %@, which represents the argument of the keyword.

Example 7.1. Example of a @dirrmtryecho Keyword

This keyword does two things, it adds a @dirrmtry directory line to the packing list, and echoes the fact that the directory is removed when deinstalling the package.

actions: [dirrmtry]
post-deinstall: <<EOD
  echo "Directory %D/%@ removed."
EOD

Example 7.2. Real Life Example, How @sample is Implemented

This keyword does three things, it adds the filename passed as an argument to @sample to the packing list, it adds to the post-install script instructions to copy the sample to the actual configuration file if it does not already exist, and it adds to the post-deinstall instructions to remove the configuration file if it has not been modified.

actions: [file]
post-install: <<EOD
  case "%@" in
  /*) sample_file="%@" ;;
  *) sample_file="%D/%@" ;;
  esac
  target_file="${sample_file%.sample}"
  if ! [ -f "${target_file}" ]; then
    /bin/cp -p "${sample_file}" "${target_file}"
  fi
EOD
pre-deinstall: <<EOD
  case "%@" in
  /*) sample_file="%@" ;;
  *) sample_file="%D/%@" ;;
  esac
  target_file="${sample_file%.sample}"
  if cmp -s "${target_file}" "${sample_file}"; then
    rm -f "${target_file}"
  else
    echo "You may need to manually remove ${target_file} if it's no longer needed."
  fi
EOD

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.