A Socket Map Server
|Smap Manual (split by section):||?|
Guile is an acronym for GNU's Ubiquitous Intelligent Language for Extensions. It provides a Scheme interpreter conforming to the R5RS language specification and a number of convenience functions. For information about the language, refer to (r5rs)Top section `Top' in Revised(5) Report on the Algorithmic Language Scheme. For a detailed description of Guile and its features, see (guile)Top section `Overview' in The Guile Reference Manual.
guile module provides an interface to Guile which
allows for writing Smap modules in Scheme. The module is loaded
using the following configuration file statement:
module name guile [args]
Optional args are:
Enable Guile debugging and stack traces.
Disable Guile debugging and stack traces (default).
Append directories from path to the list of directories which should be searched for Scheme modules and libraries. The path must be a list of directory names, separated by colons.
This option modifies the value of Guile's
See the section Configuration and Installation in the Guile Reference Manual.
Specifies the name of a Scheme source file that must be loaded in order to initialize the module. The file is looked up using ‘%load-path’ variable.
init-args parameter supplies additional arguments to the
module. They will be accessible to the ‘script’ via
This parameter specifies the name of a function that will be invoked to perform the initialization of the module and of particular databases. Default name is ‘init’. See section Guile Initialization, for a description of initialization sequence.
Guile databases are declared using the following syntax:
database dbname modname [args] [cmdline]
where: dbname gives the name for this database and modname
is the name given to Guile module in
module statement (see
Optional args override global settings given in the
module statement. The following options are understood:
meaning is the same as for
module statement (see above),
except that they affect only this particular database.
Any additional arguments, referenced as cmdline above, are
be passed to the Guile
open-db callback function (see open-db).
Any database handled by
guile module is associated with a
virtual function table. This table is an association list which
supplies to the module the Scheme call-back functions implemented to
perform particular tasks on that database. In this list,
car of each element contains the name of a function, and
cdr gives the corresponding function. The defined function
names and their semantics are described in the following table:
Initialize the module.
Close the module, releasing any resources held by it.
Open the database.
Close the database.
Handle a socket map query
Handle a transformation request (see section Transformations).
For example, the following is a valid virtual function table:
(list (cons "open" open-module) (cons "close" close-module) (cons "query" run-query))
Apart from per-database virtual tables, there is also a global virtual function table, which is used to supply the entries missing in the former. Both tables are created during the module initialization, as described in the next subsection.
Particular virtual functions are described in Guile API.
Guile modules are executed in a specially prepared environment.
Current error port is redirected so that everything written to it ends
up in the
smapd error stream. So, if
writing its log to syslog, everything you write to
‘(current-error-port)’ will be written to syslog as well. The
port is line-buffered. For example, the following code:
(with-output-to-port (current-error-port) (lambda () (display "The diagnostics follows:") (newline) (display "Module opened") (newline)))
will result in two lines in your syslog file, which will look like
Jun 19 12:49:05 netbox smapd: The diagnostics follows Jun 19 12:49:05 netbox smapd: Module opened
For any debugging output, use
smap-debug-port. This port is
configured so that everything written to it is explicitly marked as
being debug output. If
smapd logs to stderr, it will be
prefixed with ‘DEBUG:’, and if it logs to syslog, the output will
be logged with ‘LOG_DEBUG’ priority.
Finally, current output port is closed for any functions, excepting ‘query’ (see query-db). For ‘query’ function, it is redirected so that anything written to it is reformatted according to the socket map protocol (see section The Sockmap Protocol) and sent back as a reply to the client.
module configuration statement causes loading and
initialization of the
module modname guile [init-script=‘script’] \ [init-fun=function"]
Upon module initialization stage, the module attempts to load the
file named ‘script’. The file is loaded using
primitive-load-path call (see primitive-load-path: (guile)Loading section `Loading' in The Guile Reference Manual), i.e. it is searched in the Guile
load path. The
init-fun parameter supplies the name of the
initialization function. This Scheme function returns virtual
function tables for the module itself and for each database that uses
this module. It must be declared as follows:
(define (function arg) …)
This function is called several times. First of all, it is called after
script is loaded. This time it is given
#f as its
argument, and its return value is saved as a global function table.
Then, it is called for each
database statement that uses module
modname (defined in the
module statement above), e.g.:
database dbname modname …
This time, it is given dbname as its argument and its return is stored as the virtual function table for this particular database.
The following example function returns a complete virtual function table:
(define (my-smap-init arg) (list (cons "init" db-init) (cons "done" db-done) (cons "open" db-open) (cons "close" db-close) (cons "query" db-query) (cons "xform" db-xform)))
This subsection describes callback functions that a Guile database module must provide. The description of each function begins with the function prototype and its entry in the virtual function table.
(cons "open" open-db)
Open the database. The argument name contains database name as
dbname of the
(see section Databases). Optional argument args is a list of
command line parameters obtained from cmdline in
statement (see guile-cmdline). For example, if the configuration
database foo guile db=file 1 no
open-db callback will be called as:
(open-db "foo" '("db=file" "1" "no"))
open-db callback returns a database handle, i.e. an
opaque Scheme object which identifies this database, and keeps its
internal state. This value, hereinafter named dbh,
will be passed to another callback functions that need to access the
The unspecified return value indicates an error.
(cons "close" close-db)
Close the database. This function is called during the cleanup
procedure, before termination of
smapd child process. The
dbh is a database handle returned by
The return value from
close-db is ignored. To communicate
errors to the daemon, throw an exception.
(cons "close" close-db)
Perform the query. Arguments are:
A database handle returned by
The map name.
The lookup key
If this query came over a UNIX socket, this argument is ‘()’. Otherwise, if the query came over an INET socket, rest is a list of two network socket addresses (see (guile)Network Socket Address section `Network Socket Address' in The Guile Reference Manual): first element is the address of the remote party (client), second element is the address of the server that is handling the query.
This function must write the reply, terminated with a newline, to the current output port, e.g.:
(define-public (smap-query handle map arg . rest) (display "NOTFOUND") (newline))
(cons "xform" xform-db)
Transform the argument arg. Arguments dbh and rest have the same meaning as in query-db.
Returns transformed value or ‘#f’ if no transformation applies. This callback may be used to alter map or key values using ‘guile’ module (see section Transformations). The following example function removes optional domain part from its argument:
(define (smap-xform handle arg . rest) (let ((arg-parts (string-split arg #\@))) (if (null? (cdr arg-parts)) #f (car arg-parts))))
The following snippet from the ‘smapd.conf’ file shows how to apply it:
database localpart guile init-script=local.scm dispatch key like *@* transform key localpart
|Smap Manual (split by section):||?|
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.