aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/articles/rc-scripting/_index.po
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/content/en/articles/rc-scripting/_index.po')
-rw-r--r--documentation/content/en/articles/rc-scripting/_index.po1620
1 files changed, 1620 insertions, 0 deletions
diff --git a/documentation/content/en/articles/rc-scripting/_index.po b/documentation/content/en/articles/rc-scripting/_index.po
new file mode 100644
index 0000000000..f90baeddb2
--- /dev/null
+++ b/documentation/content/en/articles/rc-scripting/_index.po
@@ -0,0 +1,1620 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2023-05-21 14:43-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/articles/rc-scripting/_index.adoc:1
+#, no-wrap
+msgid "A guide to writing new rc.d scripts and understanding those already written"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/articles/rc-scripting/_index.adoc:1
+#: documentation/content/en/articles/rc-scripting/_index.adoc:12
+#, no-wrap
+msgid "Practical rc.d scripting in BSD"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:45
+msgid "Abstract"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:49
+msgid ""
+"Beginners may find it difficult to relate the facts from the formal "
+"documentation on the BSD [.filename]#rc.d# framework with the practical "
+"tasks of [.filename]#rc.d# scripting. In this article, we consider a few "
+"typical cases of increasing complexity, show [.filename]#rc.d# features "
+"suited for each case, and discuss how they work. Such an examination should "
+"provide reference points for further study of the design and efficient "
+"application of [.filename]#rc.d#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:51
+msgid "'''"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:55
+#, no-wrap
+msgid "Introduction"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:61
+msgid ""
+"The historical BSD had a monolithic startup script, [.filename]#/etc/rc#. "
+"It was invoked by man:init[8] at system boot time and performed all userland "
+"tasks required for multi-user operation: checking and mounting file systems, "
+"setting up the network, starting daemons, and so on. The precise list of "
+"tasks was not the same in every system; admins needed to customize it. With "
+"few exceptions, [.filename]#/etc/rc# had to be modified, and true hackers "
+"liked it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:67
+msgid ""
+"The real problem with the monolithic approach was that it provided no "
+"control over the individual components started from [.filename]#/etc/rc#. "
+"For instance, [.filename]#/etc/rc# could not restart a single daemon. The "
+"system admin had to find the daemon process by hand, kill it, wait until it "
+"actually exited, then browse through [.filename]#/etc/rc# for the flags, and "
+"finally type the full command line to start the daemon again. The task "
+"would become even more difficult and prone to errors if the service to "
+"restart consisted of more than one daemon or demanded additional actions. "
+"In a few words, the single script failed to fulfil what scripts are for: to "
+"make the system admin's life easier."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:74
+msgid ""
+"Later there was an attempt to split out some parts of [.filename]#/etc/rc# "
+"for the sake of starting the most important subsystems separately. The "
+"notorious example was [.filename]#/etc/netstart# to bring up networking. It "
+"did allow for accessing the network from single-user mode, but it did not "
+"integrate well into the automatic startup process because parts of its code "
+"needed to interleave with actions essentially unrelated to networking. That "
+"was why [.filename]#/etc/netstart# mutated into [.filename]#/etc/rc."
+"network#. The latter was no longer an ordinary script; it comprised of "
+"large, tangled man:sh[1] functions called from [.filename]#/etc/rc# at "
+"different stages of system startup. However, as the startup tasks grew "
+"diverse and sophisticated, the \"quasi-modular\" approach became even more "
+"of a drag than the monolithic [.filename]#/etc/rc# had been."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:82
+msgid ""
+"Without a clean and well-designed framework, the startup scripts had to bend "
+"over backwards to satisfy the needs of rapidly developing BSD-based "
+"operating systems. It became obvious at last that more steps are necessary "
+"on the way to a fine-grained and extensible [.filename]#rc# system. Thus "
+"BSD [.filename]#rc.d# was born. Its acknowledged fathers were Luke Mewburn "
+"and the NetBSD community. Later it was imported into FreeBSD. Its name "
+"refers to the location of system scripts for individual services, which is "
+"in [.filename]#/etc/rc.d#. Soon we will learn about more components of the "
+"[.filename]#rc.d# system and see how the individual scripts are invoked."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:93
+msgid ""
+"The basic ideas behind BSD [.filename]#rc.d# are _fine modularity_ and "
+"__code reuse__. _Fine modularity_ means that each basic \"service\" such as "
+"a system daemon or primitive startup task gets its own man:sh[1] script able "
+"to start the service, stop it, reload it, check its status. A particular "
+"action is chosen by the command-line argument to the script. The [."
+"filename]#/etc/rc# script still drives system startup, but now it merely "
+"invokes the smaller scripts one by one with the `start` argument. It is "
+"easy to perform shutdown tasks as well by running the same set of scripts "
+"with the `stop` argument, which is done by [.filename]#/etc/rc.shutdown#. "
+"Note how closely this follows the Unix way of having a set of small "
+"specialized tools, each fulfilling its task as well as possible. _Code "
+"reuse_ means that common operations are implemented as man:sh[1] functions "
+"and collected in [.filename]#/etc/rc.subr#. Now a typical script can be "
+"just a few lines' worth of man:sh[1] code. Finally, an important part of "
+"the [.filename]#rc.d# framework is man:rcorder[8], which helps [.filename]#/"
+"etc/rc# to run the small scripts orderly with respect to dependencies "
+"between them. It can help [.filename]#/etc/rc.shutdown#, too, because the "
+"proper order for the shutdown sequence is opposite to that of startup."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:101
+msgid ""
+"The BSD [.filename]#rc.d# design is described in <<lukem, the original "
+"article by Luke Mewburn>>, and the [.filename]#rc.d# components are "
+"documented in great detail in <<manpages, the respective manual pages>>. "
+"However, it might not appear obvious to an [.filename]#rc.d# newbie how to "
+"tie the numerous bits and pieces together to create a well-styled script for "
+"a particular task. Therefore this article will try a different approach to "
+"describe [.filename]#rc.d#. It will show which features should be used in a "
+"number of typical cases, and why. Note that this is not a how-to document "
+"because our aim is not at giving ready-made recipes, but at showing a few "
+"easy entrances into the [.filename]#rc.d# realm. Neither is this article a "
+"replacement for the relevant manual pages. Do not hesitate to refer to them "
+"for more formal and complete documentation while reading this article."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:105
+msgid ""
+"There are prerequisites to understanding this article. First of all, you "
+"should be familiar with the man:sh[1] scripting language to master [."
+"filename]#rc.d#. In addition, you should know how the system performs "
+"userland startup and shutdown tasks, which is described in man:rc[8]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:108
+msgid ""
+"This article focuses on the FreeBSD branch of [.filename]#rc.d#. "
+"Nevertheless, it may be useful to NetBSD developers, too, because the two "
+"branches of BSD [.filename]#rc.d# not only share the same design but also "
+"stay similar in their aspects visible to script authors."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:110
+#, no-wrap
+msgid "Outlining the task"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:114
+msgid ""
+"A little consideration before starting `$EDITOR` will not hurt. To write a "
+"well-tempered [.filename]#rc.d# script for a system service, we should be "
+"able to answer the following questions first:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:116
+msgid "Is the service mandatory or optional?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:117
+msgid ""
+"Will the script serve a single program, e.g., a daemon, or perform more "
+"complex actions?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:118
+msgid "Which other services will our service depend on, and vice versa?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:120
+msgid ""
+"From the examples that follow we will see why it is important to know the "
+"answers to these questions."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:122
+#, no-wrap
+msgid "A dummy script"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:125
+msgid ""
+"The following script just emits a message each time the system boots up:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:129
+#, no-wrap
+msgid "#!/bin/sh <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:131
+#, no-wrap
+msgid ". /etc/rc.subr <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:135
+#, no-wrap
+msgid ""
+"name=\"dummy\" <.>\n"
+"start_cmd=\"${name}_start\" <.>\n"
+"stop_cmd=\":\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:140
+#, no-wrap
+msgid ""
+"dummy_start() <.>\n"
+"{\n"
+"\techo \"Nothing started.\"\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:143
+#, no-wrap
+msgid ""
+"load_rc_config $name <.>\n"
+"run_rc_command \"$1\" <.>\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:146
+msgid "Things to note are:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:152
+msgid ""
+"&#10122; An interpreted script should begin with the magic \"shebang\" "
+"line. That line specifies the interpreter program for the script. Due to "
+"the shebang line, the script can be invoked exactly like a binary program "
+"provided that it has the execute bit set. (See man:chmod[1].) For example, "
+"a system admin can run our script manually, from the command line:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:156
+#, no-wrap
+msgid "# /etc/rc.d/dummy start\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:162
+msgid ""
+"To be properly managed by the [.filename]#rc.d# framework, its scripts need "
+"to be written in the man:sh[1] language. If you have a service or port that "
+"uses a binary control utility or a startup routine written in another "
+"language, install that element in [.filename]#/usr/sbin# (for the system) or "
+"[.filename]#/usr/local/sbin# (for ports) and call it from a man:sh[1] script "
+"in the appropriate [.filename]#rc.d# directory."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:167
+msgid ""
+"If you would like to learn the details of why [.filename]#rc.d# scripts must "
+"be written in the man:sh[1] language, see how [.filename]#/etc/rc# invokes "
+"them by means of `run_rc_script`, then study the implementation of "
+"`run_rc_script` in [.filename]#/etc/rc.subr#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:173
+msgid ""
+"&#10123; In [.filename]#/etc/rc.subr#, a number of man:sh[1] functions are "
+"defined for an [.filename]#rc.d# script to use. The functions are "
+"documented in man:rc.subr[8]. While it is theoretically possible to write "
+"an [.filename]#rc.d# script without ever using man:rc.subr[8], its functions "
+"prove extremely handy and make the job an order of magnitude easier. So it "
+"is no surprise that everybody resorts to man:rc.subr[8] in [.filename]#rc.d# "
+"scripts. We are not going to be an exception."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:176
+msgid ""
+"An [.filename]#rc.d# script must \"source\"[.filename]#/etc/rc.subr# "
+"(include it using \"`.`\") _before_ it calls man:rc.subr[8] functions so "
+"that man:sh[1] has an opportunity to learn the functions. The preferred "
+"style is to source [.filename]#/etc/rc.subr# first of all."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:180
+msgid ""
+"Some useful functions related to networking are provided by another include "
+"file, [.filename]#/etc/network.subr#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:185
+msgid ""
+"&#10124; [[name-var]]The mandatory variable `name` specifies the name of our "
+"script. It is required by man:rc.subr[8]. That is, each [.filename]#rc.d# "
+"script _must_ set `name` before it calls man:rc.subr[8] functions."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:189
+msgid ""
+"Now it is the right time to choose a unique name for our script once and for "
+"all. We will use it in a number of places while developing the script. For "
+"a start, let us give the same name to the script file, too."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:196
+msgid ""
+"The current style of [.filename]#rc.d# scripting is to enclose values "
+"assigned to variables in double quotes. Keep in mind that it is just a "
+"style issue that may not always be applicable. You can safely omit quotes "
+"from around simple words without man:sh[1] metacharacters in them, while in "
+"certain cases you will need single quotes to prevent any interpretation of "
+"the value by man:sh[1]. A programmer should be able to tell the language "
+"syntax from style conventions and use both of them wisely."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:202
+msgid ""
+"&#10125; The main idea behind man:rc.subr[8] is that an [.filename]#rc.d# "
+"script provides handlers, or methods, for man:rc.subr[8] to invoke. In "
+"particular, `start`, `stop`, and other arguments to an [.filename]#rc.d# "
+"script are handled this way. A method is a man:sh[1] expression stored in a "
+"variable named `argument_cmd`, where _argument_ corresponds to what can be "
+"specified on the script's command line. We will see later how man:rc."
+"subr[8] provides default methods for the standard arguments."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:207
+msgid ""
+"To make the code in [.filename]#rc.d# more uniform, it is common to use "
+"`${name}` wherever appropriate. Thus a number of lines can be just copied "
+"from one script to another."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:211
+msgid ""
+"&#10126; We should keep in mind that man:rc.subr[8] provides default methods "
+"for the standard arguments. Consequently, we must override a standard "
+"method with a no-op man:sh[1] expression if we want it to do nothing."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:214
+msgid ""
+"&#10127; The body of a sophisticated method can be implemented as a "
+"function. It is a good idea to make the function name meaningful."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:218
+msgid ""
+"It is strongly recommended to add the prefix `${name}` to the names of all "
+"functions defined in our script so they never clash with the functions from "
+"man:rc.subr[8] or another common include file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:222
+msgid ""
+"&#10128; This call to man:rc.subr[8] loads man:rc.conf[5] variables. Our "
+"script makes no use of them yet, but it still is recommended to load man:rc."
+"conf[5] because there can be man:rc.conf[5] variables controlling man:rc."
+"subr[8] itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:225
+msgid ""
+"&#10129; Usually this is the last command in an [.filename]#rc.d# script. "
+"It invokes the man:rc.subr[8] machinery to perform the requested action "
+"using the variables and methods our script has provided."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:227
+#, no-wrap
+msgid "A configurable dummy script"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:237
+msgid ""
+"Now let us add some controls to our dummy script. As you may know, [."
+"filename]#rc.d# scripts are controlled with man:rc.conf[5]. Fortunately, "
+"man:rc.subr[8] hides all the complications from us. The following script "
+"uses man:rc.conf[5] via man:rc.subr[8] to see whether it is enabled in the "
+"first place, and to fetch a message to show at boot time. These two tasks "
+"in fact are independent. On the one hand, an [.filename]#rc.d# script can "
+"just support enabling and disabling its service. On the other hand, a "
+"mandatory [.filename]#rc.d# script can have configuration variables. We "
+"will do both things in the same script though:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:241
+#: documentation/content/en/articles/rc-scripting/_index.adoc:332
+#: documentation/content/en/articles/rc-scripting/_index.adoc:389
+#: documentation/content/en/articles/rc-scripting/_index.adoc:621
+#: documentation/content/en/articles/rc-scripting/_index.adoc:752
+#, no-wrap
+msgid "#!/bin/sh\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:243
+#: documentation/content/en/articles/rc-scripting/_index.adoc:334
+#: documentation/content/en/articles/rc-scripting/_index.adoc:391
+#: documentation/content/en/articles/rc-scripting/_index.adoc:628
+#: documentation/content/en/articles/rc-scripting/_index.adoc:754
+#, no-wrap
+msgid ". /etc/rc.subr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:246
+#, no-wrap
+msgid ""
+"name=dummy\n"
+"rcvar=dummy_enable <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:249
+#, no-wrap
+msgid ""
+"start_cmd=\"${name}_start\"\n"
+"stop_cmd=\":\"\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:253
+#, no-wrap
+msgid ""
+"load_rc_config $name <.>\n"
+": ${dummy_enable:=no} <.>\n"
+": ${dummy_msg=\"Nothing started.\"} <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:258
+#, no-wrap
+msgid ""
+"dummy_start()\n"
+"{\n"
+"\techo \"$dummy_msg\" <.>\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:260
+#, no-wrap
+msgid "run_rc_command \"$1\"\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:263
+msgid "What changed in this example?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:265
+msgid ""
+"&#10122; The variable `rcvar` specifies the name of the ON/OFF knob variable."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:267
+msgid ""
+"&#10123; Now `load_rc_config` is invoked earlier in the script, before any "
+"man:rc.conf[5] variables are accessed."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:273
+msgid ""
+"While examining [.filename]#rc.d# scripts, keep in mind that man:sh[1] "
+"defers the evaluation of expressions in a function until the latter is "
+"called. Therefore it is not an error to invoke `load_rc_config` as late as "
+"just before `run_rc_command` and still access man:rc.conf[5] variables from "
+"the method functions exported to `run_rc_command`. This is because the "
+"method functions are to be called by `run_rc_command`, which is invoked "
+"_after_ `load_rc_config`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:279
+msgid ""
+"&#10124; A warning will be emitted by `run_rc_command` if `rcvar` itself is "
+"set, but the indicated knob variable is unset. If your [.filename]#rc.d# "
+"script is for the base system, you should add a default setting for the knob "
+"to [.filename]#/etc/defaults/rc.conf# and document it in man:rc.conf[5]. "
+"Otherwise it is your script that should provide a default setting for the "
+"knob. The canonical approach to the latter case is shown in the example."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:286
+msgid ""
+"You can make man:rc.subr[8] act as though the knob is set to `ON`, "
+"irrespective of its current setting, by prefixing the argument to the script "
+"with `one` or `force`, as in `onestart` or `forcestop`. Keep in mind though "
+"that `force` has other dangerous effects we will touch upon below, while "
+"`one` just overrides the ON/OFF knob. E.g., assume that `dummy_enable` is "
+"`OFF`. The following command will run the `start` method in spite of the "
+"setting:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:290
+#, no-wrap
+msgid "# /etc/rc.d/dummy onestart\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:297
+msgid ""
+"&#10125; Now the message to be shown at boot time is no longer hard-coded in "
+"the script. It is specified by an man:rc.conf[5] variable named "
+"`dummy_msg`. This is a trivial example of how man:rc.conf[5] variables can "
+"control an [.filename]#rc.d# script."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:302
+msgid ""
+"The names of all man:rc.conf[5] variables used exclusively by our script "
+"_must_ have the same prefix: `${name}_`. For example: `dummy_mode`, "
+"`dummy_state_file`, and so on."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:307
+msgid ""
+"While it is possible to use a shorter name internally, e.g., just `msg`, "
+"adding the unique prefix `${name}_` to all global names introduced by our "
+"script will save us from possible collisions with the man:rc.subr[8] "
+"namespace."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:310
+msgid ""
+"As a rule, [.filename]#rc.d# scripts of the base system need not provide "
+"defaults for their man:rc.conf[5] variables because the defaults should be "
+"set in [.filename]#/etc/defaults/rc.conf# instead. On the other hand, [."
+"filename]#rc.d# scripts for ports should provide the defaults as shown in "
+"the example."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:314
+msgid ""
+"&#10126; Here we use `dummy_msg` to actually control our script, i.e., to "
+"emit a variable message. Use of a shell function is overkill here, since it "
+"only runs a single command; an equally valid alternative is:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:318
+#, no-wrap
+msgid "start_cmd=\"echo \\\"$dummy_msg\\\"\"\n"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:321
+#, no-wrap
+msgid "Startup and shutdown of a simple daemon"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:328
+msgid ""
+"We said earlier that man:rc.subr[8] could provide default methods. "
+"Obviously, such defaults cannot be too general. They are suited for the "
+"common case of starting and shutting down a simple daemon program. Let us "
+"assume now that we need to write an [.filename]#rc.d# script for such a "
+"daemon called `mumbled`. Here it is:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:337
+#: documentation/content/en/articles/rc-scripting/_index.adoc:394
+#: documentation/content/en/articles/rc-scripting/_index.adoc:631
+#, no-wrap
+msgid ""
+"name=mumbled\n"
+"rcvar=mumbled_enable\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:339
+#, no-wrap
+msgid "command=\"/usr/sbin/${name}\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:342
+#: documentation/content/en/articles/rc-scripting/_index.adoc:440
+#: documentation/content/en/articles/rc-scripting/_index.adoc:646
+#, no-wrap
+msgid ""
+"load_rc_config $name\n"
+"run_rc_command \"$1\"\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:346
+msgid ""
+"Pleasingly simple, isn't it? Let us examine our little script. The only new "
+"thing to note is as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:350
+msgid ""
+"&#10122; The `command` variable is meaningful to man:rc.subr[8]. If it is "
+"set, man:rc.subr[8] will act according to the scenario of serving a "
+"conventional daemon. In particular, the default methods will be provided "
+"for such arguments: `start`, `stop`, `restart`, `poll`, and `status`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:359
+msgid ""
+"The daemon will be started by running `$command` with command-line flags "
+"specified by `$mumbled_flags`. Thus all the input data for the default "
+"`start` method are available in the variables set by our script. Unlike "
+"`start`, other methods may require additional information about the process "
+"started. For instance, `stop` must know the PID of the process to terminate "
+"it. In the present case, man:rc.subr[8] will scan through the list of all "
+"processes, looking for a process with its name equal to `procname`. The "
+"latter is another variable of meaning to man:rc.subr[8], and its value "
+"defaults to that of `command`. In other words, when we set `command`, "
+"`procname` is effectively set to the same value. This enables our script to "
+"kill the daemon and to check if it is running in the first place."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:366
+msgid ""
+"Some programs are in fact executable scripts. The system runs such a script "
+"by starting its interpreter and passing the name of the script to it as a "
+"command-line argument. This is reflected in the list of processes, which "
+"can confuse man:rc.subr[8]. You should additionally set "
+"`command_interpreter` to let man:rc.subr[8] know the actual name of the "
+"process if `$command` is a script."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:371
+msgid ""
+"For each [.filename]#rc.d# script, there is an optional man:rc.conf[5] "
+"variable that takes precedence over `command`. Its name is constructed as "
+"follows: `${name}_program`, where `name` is the mandatory variable we "
+"discussed <<name-var, earlier>>. E.g., in this case it will be "
+"`mumbled_program`. It is man:rc.subr[8] that arranges `${name}_program` to "
+"override `command`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:375
+msgid ""
+"Of course, man:sh[1] will permit you to set `${name}_program` from man:rc."
+"conf[5] or the script itself even if `command` is unset. In that case, the "
+"special properties of `${name}_program` are lost, and it becomes an ordinary "
+"variable your script can use for its own purposes. However, the sole use of "
+"`${name}_program` is discouraged because using it together with `command` "
+"became an idiom of [.filename]#rc.d# scripting."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:378
+msgid ""
+"For more detailed information on default methods, refer to man:rc.subr[8]."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:380
+#, no-wrap
+msgid "Startup and shutdown of an advanced daemon"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:385
+msgid ""
+"Let us add some meat onto the bones of the previous script and make it more "
+"complex and featureful. The default methods can do a good job for us, but "
+"we may need some of their aspects tweaked. Now we will learn how to tune "
+"the default methods to our needs."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:397
+#, no-wrap
+msgid ""
+"command=\"/usr/sbin/${name}\"\n"
+"command_args=\"mock arguments > /dev/null 2>&1\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:399
+#, no-wrap
+msgid "pidfile=\"/var/run/${name}.pid\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:401
+#, no-wrap
+msgid "required_files=\"/etc/${name}.conf /usr/share/misc/${name}.rules\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:403
+#, no-wrap
+msgid "sig_reload=\"USR1\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:406
+#, no-wrap
+msgid ""
+"start_precmd=\"${name}_prestart\" <.>\n"
+"stop_postcmd=\"echo Bye-bye\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:408
+#, no-wrap
+msgid "extra_commands=\"reload plugh xyzzy\" <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:411
+#, no-wrap
+msgid ""
+"plugh_cmd=\"mumbled_plugh\" <.>\n"
+"xyzzy_cmd=\"echo 'Nothing happens.'\"\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:432
+#, no-wrap
+msgid ""
+"mumbled_prestart()\n"
+"{\n"
+"\tif checkyesno mumbled_smart; then <.>\n"
+"\t\trc_flags=\"-o smart ${rc_flags}\" <.>\n"
+"\tfi\n"
+"\tcase \"$mumbled_mode\" in\n"
+"\tfoo)\n"
+"\t\trc_flags=\"-frotz ${rc_flags}\"\n"
+"\t\t;;\n"
+"\tbar)\n"
+"\t\trc_flags=\"-baz ${rc_flags}\"\n"
+"\t\t;;\n"
+"\t*)\n"
+"\t\twarn \"Invalid value for mumbled_mode\" <.>\n"
+"\t\treturn 1 <.>\n"
+"\t\t;;\n"
+"\tesac\n"
+"\trun_rc_command xyzzy <.>\n"
+"\treturn 0\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:437
+#, no-wrap
+msgid ""
+"mumbled_plugh() <.>\n"
+"{\n"
+"\techo 'A hollow voice says \"plugh\".'\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:445
+msgid ""
+"&#10122; Additional arguments to `$command` can be passed in "
+"`command_args`. They will be added to the command line after "
+"`$mumbled_flags`. Since the final command line is passed to `eval` for its "
+"actual execution, input and output redirections can be specified in "
+"`command_args`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:452
+msgid ""
+"_Never_ include dashed options, like `-X` or `--foo`, in `command_args`. "
+"The contents of `command_args` will appear at the end of the final command "
+"line, hence they are likely to follow arguments present in `${name}_flags`; "
+"but most commands will not recognize dashed options after ordinary "
+"arguments. A better way of passing additional options to `$command` is to "
+"add them to the beginning of `${name}_flags`. Another way is to modify "
+"`rc_flags` <<rc-flags, as shown later>>."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:456
+msgid ""
+"&#10123; A good-mannered daemon should create a _pidfile_ so that its "
+"process can be found more easily and reliably. The variable `pidfile`, if "
+"set, tells man:rc.subr[8] where it can find the pidfile for its default "
+"methods to use."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:461
+msgid ""
+"In fact, man:rc.subr[8] will also use the pidfile to see if the daemon is "
+"already running before starting it. This check can be skipped by using the "
+"`faststart` argument."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:466
+msgid ""
+"&#10124; If the daemon cannot run unless certain files exist, just list them "
+"in `required_files`, and man:rc.subr[8] will check that those files do exist "
+"before starting the daemon. There also are `required_dirs` and "
+"`required_vars` for directories and environment variables, respectively. "
+"They all are described in detail in man:rc.subr[8]."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:470
+msgid ""
+"The default method from man:rc.subr[8] can be forced to skip the "
+"prerequisite checks by using `forcestart` as the argument to the script."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:476
+msgid ""
+"&#10125; We can customize signals to send to the daemon in case they differ "
+"from the well-known ones. In particular, `sig_reload` specifies the signal "
+"that makes the daemon reload its configuration; it is SIGHUP by default. "
+"Another signal is sent to stop the daemon process; the default is SIGTERM, "
+"but this can be changed by setting `sig_stop` appropriately."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:481
+msgid ""
+"The signal names should be specified to man:rc.subr[8] without the `SIG` "
+"prefix, as it is shown in the example. The FreeBSD version of man:kill[1] "
+"can recognize the `SIG` prefix, but the versions from other OS types may not."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:486
+msgid ""
+"&#10126;&#10127; Performing additional tasks before or after the default "
+"methods is easy. For each command-argument supported by our script, we can "
+"define `argument_precmd` and `argument_postcmd`. These man:sh[1] commands "
+"are invoked before and after the respective method, as it is evident from "
+"their names."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:492
+msgid ""
+"Overriding a default method with a custom `argument_cmd` still does not "
+"prevent us from making use of `argument_precmd` or `argument_postcmd` if we "
+"need to. In particular, the former is good for checking custom, "
+"sophisticated conditions that should be met before performing the command "
+"itself. Using `argument_precmd` along with `argument_cmd` lets us logically "
+"separate the checks from the action."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:495
+msgid ""
+"Do not forget that you can cram any valid man:sh[1] expressions into the "
+"methods, pre-, and post-commands you define. Just invoking a function that "
+"makes the real job is a good style in most cases, but never let style limit "
+"your understanding of what is going on behind the curtain."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:498
+msgid ""
+"&#10128; If we would like to implement custom arguments, which can also be "
+"thought of as _commands_ to our script, we need to list them in "
+"`extra_commands` and provide methods to handle them."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:506
+msgid ""
+"The `reload` command is special. On the one hand, it has a preset method in "
+"man:rc.subr[8]. On the other hand, `reload` is not offered by default. The "
+"reason is that not all daemons use the same reload mechanism and some have "
+"nothing to reload at all. So we need to ask explicitly that the builtin "
+"functionality be provided. We can do so via `extra_commands`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:510
+msgid ""
+"What do we get from the default method for `reload`? Quite often daemons "
+"reload their configuration upon reception of a signal - typically, SIGHUP. "
+"Therefore man:rc.subr[8] attempts to reload the daemon by sending a signal "
+"to it. The signal is preset to SIGHUP but can be customized via "
+"`sig_reload` if necessary."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:515
+msgid ""
+"&#10129;&#9454; Our script supports two non-standard commands, `plugh` and "
+"`xyzzy`. We saw them listed in `extra_commands`, and now it is time to "
+"provide methods for them. The method for `xyzzy` is just inlined while that "
+"for `plugh` is implemented as the `mumbled_plugh` function."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:519
+msgid ""
+"Non-standard commands are not invoked during startup or shutdown. Usually "
+"they are for the system admin's convenience. They can also be used from "
+"other subsystems, e.g., man:devd[8] if specified in man:devd.conf[5]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:522
+msgid ""
+"The full list of available commands can be found in the usage line printed "
+"by man:rc.subr[8] when the script is invoked without arguments. For "
+"example, here is the usage line from the script under study:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:527
+#, no-wrap
+msgid ""
+"# /etc/rc.d/mumbled\n"
+"Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:534
+msgid ""
+"&#9453; A script can invoke its own standard or non-standard commands if "
+"needed. This may look similar to calling functions, but we know that "
+"commands and shell functions are not always the same thing. For instance, "
+"`xyzzy` is not implemented as a function here. In addition, there can be a "
+"pre-command and post-command, which should be invoked orderly. So the "
+"proper way for a script to run its own command is by means of man:rc."
+"subr[8], as shown in the example."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:540
+msgid ""
+"&#10130; A handy function named `checkyesno` is provided by man:rc.subr[8]. "
+"It takes a variable name as its argument and returns a zero exit code if and "
+"only if the variable is set to `YES`, or `TRUE`, or `ON`, or `1`, case "
+"insensitive; a non-zero exit code is returned otherwise. In the latter "
+"case, the function tests the variable for being set to `NO`, `FALSE`, `OFF`, "
+"or `0`, case insensitive; it prints a warning message if the variable "
+"contains anything else, i.e., junk."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:542
+msgid ""
+"Keep in mind that for man:sh[1] a zero exit code means true and a non-zero "
+"exit code means false."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:547
+msgid ""
+"The `checkyesno` function takes a __variable name__. Do not pass the "
+"expanded _value_ of a variable to it; it will not work as expected."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:549
+msgid "The following is the correct usage of `checkyesno`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:555
+#, no-wrap
+msgid ""
+"if checkyesno mumbled_enable; then\n"
+" foo\n"
+"fi\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:558
+msgid ""
+"On the contrary, calling `checkyesno` as shown below will not work - at "
+"least not as expected:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:564
+#, no-wrap
+msgid ""
+"if checkyesno \"${mumbled_enable}\"; then\n"
+" foo\n"
+"fi\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:569
+msgid ""
+"&#10131; [[rc-flags]]We can affect the flags to be passed to `$command` by "
+"modifying `rc_flags` in `$start_precmd`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:573
+msgid ""
+"&#9451; In certain cases we may need to emit an important message that "
+"should go to `syslog` as well. This can be done easily with the following "
+"man:rc.subr[8] functions: `debug`, `info`, `warn`, and `err`. The latter "
+"function then exits the script with the code specified."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:577
+msgid ""
+"&#9452; The exit codes from methods and their pre-commands are not just "
+"ignored by default. If `argument_precmd` returns a non-zero exit code, the "
+"main method will not be performed. In turn, `argument_postcmd` will not be "
+"invoked unless the main method returns a zero exit code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:581
+msgid ""
+"However, man:rc.subr[8] can be instructed from the command line to ignore "
+"those exit codes and invoke all commands anyway by prefixing an argument "
+"with `force`, as in `forcestart`."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:584
+#, no-wrap
+msgid "Connecting a script to the rc.d framework"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:591
+msgid ""
+"After a script has been written, it needs to be integrated into [."
+"filename]#rc.d#. The crucial step is to install the script in [.filename]#/"
+"etc/rc.d# (for the base system) or [.filename]#/usr/local/etc/rc.d# (for "
+"ports). Both [.filename]#bsd.prog.mk# and [.filename]#bsd.port.mk# provide "
+"convenient hooks for that, and usually you do not have to worry about the "
+"proper ownership and mode. System scripts should be installed from [."
+"filename]#src/libexec/rc/rc.d# through the [.filename]#Makefile# found "
+"there. Port scripts can be installed using `USE_RC_SUBR` as described "
+"extref:{porters-handbook}[in the Porter's Handbook, rc-scripts]."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:596
+msgid ""
+"However, we should consider beforehand the place of our script in the system "
+"startup sequence. The service handled by our script is likely to depend on "
+"other services. For instance, a network daemon cannot function without the "
+"network interfaces and routing up and running. Even if a service seems to "
+"demand nothing, it can hardly start before the basic filesystems have been "
+"checked and mounted."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:602
+msgid ""
+"We mentioned man:rcorder[8] already. Now it is time to have a close look at "
+"it. In a nutshell, man:rcorder[8] takes a set of files, examines their "
+"contents, and prints a dependency-ordered list of files from the set to "
+"`stdout`. The point is to keep dependency information _inside_ the files so "
+"that each file can speak for itself only. A file can specify the following "
+"information:"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:604
+msgid ""
+"the names of the \"conditions\" (which means services to us) it __provides__;"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:605
+msgid "the names of the \"conditions\" it __requires__;"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:606
+msgid "the names of the \"conditions\" this file should run __before__;"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:607
+msgid ""
+"additional _keywords_ that can be used to select a subset from the whole set "
+"of files (man:rcorder[8] can be instructed via options to include or omit "
+"the files having particular keywords listed.)"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:612
+msgid ""
+"It is no surprise that man:rcorder[8] can handle only text files with a "
+"syntax close to that of man:sh[1]. That is, special lines understood by man:"
+"rcorder[8] look like man:sh[1] comments. The syntax of such special lines "
+"is rather rigid to simplify their processing. See man:rcorder[8] for "
+"details."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:615
+msgid ""
+"Besides using man:rcorder[8] special lines, a script can insist on its "
+"dependency upon another service by just starting it forcibly. This can be "
+"needed when the other service is optional and will not start by itself "
+"because the system admin has disabled it mistakenly in man:rc.conf[5]."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:617
+msgid ""
+"With this general knowledge in mind, let us consider the simple daemon "
+"script enhanced with dependency stuff:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:626
+#, no-wrap
+msgid ""
+"# PROVIDE: mumbled oldmumble <.>\n"
+"# REQUIRE: DAEMON cleanvar frotz <.>\n"
+"# BEFORE: LOGIN <.>\n"
+"# KEYWORD: nojail shutdown <.>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:634
+#, no-wrap
+msgid ""
+"command=\"/usr/sbin/${name}\"\n"
+"start_precmd=\"${name}_prestart\"\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:643
+#, no-wrap
+msgid ""
+"mumbled_prestart()\n"
+"{\n"
+"\tif ! checkyesno frotz_enable && \\\n"
+"\t ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then\n"
+"\t\tforce_depend frotz || return 1 <.>\n"
+"\tfi\n"
+"\treturn 0\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:649
+msgid "As before, detailed analysis follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:652
+msgid ""
+"&#10122; That line declares the names of \"conditions\" our script "
+"provides. Now other scripts can record a dependency on our script by those "
+"names."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:657
+msgid ""
+"Usually a script specifies a single condition provided. However, nothing "
+"prevents us from listing several conditions there, e.g., for compatibility "
+"reasons."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:659
+msgid ""
+"In any case, the name of the main, or the only, `PROVIDE:` condition should "
+"be the same as `${name}`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:663
+msgid ""
+"&#10123;&#10124; So our script indicates which \"conditions\" provided by "
+"other scripts it depends on. According to the lines, our script asks man:"
+"rcorder[8] to put it after the script(s) providing [.filename]#DAEMON# and [."
+"filename]#cleanvar#, but before that providing [.filename]#LOGIN#."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:669
+msgid ""
+"The `BEFORE:` line should not be abused to work around an incomplete "
+"dependency list in the other script. The appropriate case for using `BEFORE:"
+"` is when the other script does not care about ours, but our script can do "
+"its task better if run before the other one. A typical real-life example is "
+"the network interfaces vs. the firewall: While the interfaces do not depend "
+"on the firewall in doing their job, the system security will benefit from "
+"the firewall being ready before there is any network traffic."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:673
+msgid ""
+"Besides conditions corresponding to a single service each, there are meta-"
+"conditions and their \"placeholder\" scripts used to ensure that certain "
+"groups of operations are performed before others. These are denoted by [."
+"filename]#UPPERCASE# names. Their list and purposes can be found in man:"
+"rc[8]."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:679
+msgid ""
+"Keep in mind that putting a service name in the `REQUIRE:` line does not "
+"guarantee that the service will actually be running by the time our script "
+"starts. The required service may fail to start or just be disabled in man:"
+"rc.conf[5]. Obviously, man:rcorder[8] cannot track such details, and man:"
+"rc[8] will not do that either. Consequently, the application started by our "
+"script should be able to cope with any required services being unavailable. "
+"In certain cases, we can help it as discussed <<forcedep, below>>"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:684
+msgid ""
+"[[keywords]]&#10125; As we remember from the above text, man:rcorder[8] "
+"keywords can be used to select or leave out some scripts. Namely any man:"
+"rcorder[8] consumer can specify through `-k` and `-s` options which keywords "
+"are on the \"keep list\" and \"skip list\", respectively. From all the "
+"files to be dependency sorted, man:rcorder[8] will pick only those having a "
+"keyword from the keep list (unless empty) and not having a keyword from the "
+"skip list."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:687
+msgid ""
+"In FreeBSD, man:rcorder[8] is used by [.filename]#/etc/rc# and [.filename]#/"
+"etc/rc.shutdown#. These two scripts define the standard list of FreeBSD [."
+"filename]#rc.d# keywords and their meanings as follows:"
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/articles/rc-scripting/_index.adoc:688
+#, no-wrap
+msgid "nojail"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:690
+msgid ""
+"The service is not for man:jail[8] environment. The automatic startup and "
+"shutdown procedures will ignore the script if inside a jail."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/articles/rc-scripting/_index.adoc:691
+#, no-wrap
+msgid "nostart"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:694
+msgid ""
+"The service is to be started manually or not started at all. The automatic "
+"startup procedure will ignore the script. In conjunction with the [."
+"filename]#shutdown# keyword, this can be used to write scripts that do "
+"something only at system shutdown."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/articles/rc-scripting/_index.adoc:695
+#, no-wrap
+msgid "shutdown"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:696
+msgid ""
+"This keyword is to be listed __explicitly__ if the service needs to be "
+"stopped before system shutdown."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:709
+msgid ""
+"When the system is going to shut down, [.filename]#/etc/rc.shutdown# runs. "
+"It assumes that most [.filename]#rc.d# scripts have nothing to do at that "
+"time. Therefore [.filename]#/etc/rc.shutdown# selectively invokes [."
+"filename]#rc.d# scripts with the [.filename]#shutdown# keyword, effectively "
+"ignoring the rest of the scripts. For even faster shutdown, [.filename]#/"
+"etc/rc.shutdown# passes the [.filename]#faststop# command to the scripts it "
+"runs so that they skip preliminary checks, e.g., the pidfile check. As "
+"dependent services should be stopped before their prerequisites, [."
+"filename]#/etc/rc.shutdown# runs the scripts in reverse dependency order. "
+"If writing a real [.filename]#rc.d# script, you should consider whether it "
+"is relevant at system shutdown time. E.g., if your script does its work in "
+"response to the [.filename]#start# command only, then you need not to "
+"include this keyword. However, if your script manages a service, it is "
+"probably a good idea to stop it before the system proceeds to the final "
+"stage of its shutdown sequence described in man:halt[8]. In particular, a "
+"service should be stopped explicitly if it needs considerable time or "
+"special actions to shut down cleanly. A typical example of such a service "
+"is a database engine."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:713
+msgid ""
+"[[forcedep]]&#10126; To begin with, `force_depend` should be used with much "
+"care. It is generally better to revise the hierarchy of configuration "
+"variables for your [.filename]#rc.d# scripts if they are interdependent."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:722
+msgid ""
+"If you still cannot do without `force_depend`, the example offers an idiom "
+"of how to invoke it conditionally. In the example, our `mumbled` daemon "
+"requires that another one, `frotz`, be started in advance. However, `frotz` "
+"is optional, too; and man:rcorder[8] knows nothing about such details. "
+"Fortunately, our script has access to all man:rc.conf[5] variables. If "
+"`frotz_enable` is true, we hope for the best and rely on [.filename]#rc.d# "
+"to have started `frotz`. Otherwise we forcibly check the status of "
+"`frotz`. Finally, we enforce our dependency on `frotz` if it is found to be "
+"not running. A warning message will be emitted by `force_depend` because it "
+"should be invoked only if a misconfiguration has been detected."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:724
+#, no-wrap
+msgid "Giving more flexibility to an rc.d script"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:733
+msgid ""
+"When invoked during startup or shutdown, an [.filename]#rc.d# script is "
+"supposed to act on the entire subsystem it is responsible for. E.g., [."
+"filename]#/etc/rc.d/netif# should start or stop all network interfaces "
+"described by man:rc.conf[5]. Either task can be uniquely indicated by a "
+"single command argument such as `start` or `stop`. Between startup and "
+"shutdown, [.filename]#rc.d# scripts help the admin to control the running "
+"system, and it is when the need for more flexibility and precision arises. "
+"For instance, the admin may want to add the settings of a new network "
+"interface to man:rc.conf[5] and then to start it without interfering with "
+"the operation of the existing interfaces. Next time the admin may need to "
+"shut down a single network interface. In the spirit of the command line, "
+"the respective [.filename]#rc.d# script calls for an extra argument, the "
+"interface name."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:736
+msgid ""
+"Fortunately, man:rc.subr[8] allows for passing any number of arguments to "
+"script's methods (within the system limits). Due to that, the changes in "
+"the script itself can be minimal."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:741
+msgid ""
+"How can man:rc.subr[8] gain access to the extra command-line arguments. "
+"Should it just grab them directly? Not by any means. Firstly, an man:sh[1] "
+"function has no access to the positional parameters of its caller, but man:"
+"rc.subr[8] is just a sack of such functions. Secondly, the good manner of [."
+"filename]#rc.d# dictates that it is for the main script to decide which "
+"arguments are to be passed to its methods."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:745
+msgid ""
+"So the approach adopted by man:rc.subr[8] is as follows: `run_rc_command` "
+"passes on all its arguments but the first one to the respective method "
+"verbatim. The first, omitted, argument is the name of the method itself: "
+"`start`, `stop`, etc. It will be shifted out by `run_rc_command`, so what "
+"is `$2` in the original command line will be presented as `$1` to the "
+"method, and so on."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:748
+msgid ""
+"To illustrate this opportunity, let us modify the primitive dummy script so "
+"that its messages depend on the additional arguments supplied. Here we go:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:760
+#, no-wrap
+msgid ""
+"name=\"dummy\"\n"
+"start_cmd=\"${name}_start\"\n"
+"stop_cmd=\":\"\n"
+"kiss_cmd=\"${name}_kiss\"\n"
+"extra_commands=\"kiss\"\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:769
+#, no-wrap
+msgid ""
+"dummy_start()\n"
+"{\n"
+" if [ $# -gt 0 ]; then <.>\n"
+" echo \"Greeting message: $*\"\n"
+" else\n"
+" echo \"Nothing started.\"\n"
+" fi\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:785
+#, no-wrap
+msgid ""
+"dummy_kiss()\n"
+"{\n"
+" echo -n \"A ghost gives you a kiss\"\n"
+" if [ $# -gt 0 ]; then <.>\n"
+" echo -n \" and whispers: $*\"\n"
+" fi\n"
+" case \"$*\" in\n"
+" *[.!?])\n"
+" echo\n"
+" ;;\n"
+" *)\n"
+" echo .\n"
+" ;;\n"
+" esac\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:788
+#, no-wrap
+msgid ""
+"load_rc_config $name\n"
+"run_rc_command \"$@\" <.>\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:791
+msgid "What essential changes can we notice in the script?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:796
+msgid ""
+"&#10122; All arguments you type after `start` can end up as positional "
+"parameters to the respective method. We can use them in any way according "
+"to our task, skills, and fancy. In the current example, we just pass all of "
+"them to man:echo[1] as one string in the next line - note `$*` within the "
+"double quotes. Here is how the script can be invoked now:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:801
+#, no-wrap
+msgid ""
+"# /etc/rc.d/dummy start\n"
+"Nothing started.\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:804
+#, no-wrap
+msgid ""
+"# /etc/rc.d/dummy start Hello world!\n"
+"Greeting message: Hello world!\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:808
+msgid ""
+"&#10123; The same applies to any method our script provides, not only to a "
+"standard one. We have added a custom method named `kiss`, and it can take "
+"advantage of the extra arguments not less than `start` does. E.g.:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:813
+#, no-wrap
+msgid ""
+"# /etc/rc.d/dummy kiss\n"
+"A ghost gives you a kiss.\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:816
+#, no-wrap
+msgid ""
+"# /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...\n"
+"A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:819
+msgid ""
+"&#10124; If we want just to pass all extra arguments to any method, we can "
+"merely substitute `\"$@\"` for `\"$1\"` in the last line of our script, "
+"where we invoke `run_rc_command`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:825
+msgid ""
+"An man:sh[1] programmer ought to understand the subtle difference between "
+"`$*` and `$@` as the ways to designate all positional parameters. For its "
+"in-depth discussion, refer to a good handbook on man:sh[1] scripting. _Do "
+"not_ use the expressions until you fully understand them because their "
+"misuse will result in buggy and insecure scripts."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/articles/rc-scripting/_index.adoc:832
+msgid ""
+"Currently `run_rc_command` may have a bug that prevents it from keeping the "
+"original boundaries between arguments. That is, arguments with embedded "
+"whitespace may not be processed correctly. The bug stems from `$*` misuse."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/articles/rc-scripting/_index.adoc:835
+#, no-wrap
+msgid "Further reading"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:839
+msgid ""
+"[[lukem]]http://www.mewburn.net/luke/papers/rc.d.pdf[The original article by "
+"Luke Mewburn] offers a general overview of [.filename]#rc.d# and detailed "
+"rationale for its design decisions. It provides insight on the whole [."
+"filename]#rc.d# framework and its place in a modern BSD operating system."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:842
+msgid ""
+"[[manpages]]The manual pages man:rc[8], man:rc.subr[8], and man:rcorder[8] "
+"document the [.filename]#rc.d# components in great detail. You cannot fully "
+"use the [.filename]#rc.d# power without studying the manual pages and "
+"referring to them while writing your own scripts."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/articles/rc-scripting/_index.adoc:846
+msgid ""
+"The major source of working, real-life examples is [.filename]#/etc/rc.d# in "
+"a live system. Its contents are easy and pleasant to read because most "
+"rough corners are hidden deep in man:rc.subr[8]. Keep in mind though that "
+"the [.filename]#/etc/rc.d# scripts were not written by angels, so they might "
+"suffer from bugs and suboptimal design decisions. Now you can improve them!"
+msgstr ""