saf man page on SunOS

Man page or keyword search:  
man Server   20652 pages
apropos Keyword Search (all sections)
Output format
SunOS logo
[printable version]

saf(1M)			System Administration Commands		       saf(1M)

NAME
       saf - Service Access Facility

DESCRIPTION
       The  SAF	 generalizes  the  procedures for service access so that login
       access on the local system and network access  to  local	 services  are
       managed	in  similar  ways.  Under the SAF, systems may access services
       using a variety of port monitors, including ttymon, the	listener,  and
       port monitors written expressly for a user's application. The manner in
       which a port monitor observes and manages access ports is  specific  to
       the  port monitor and not to any component of the SAF. Users may there‐
       fore extend their systems by developing and installing their  own  port
       monitors.  One  of  the important features of the SAF is that it can be
       extended in this way by users.

       Relative to the SAF, a service is a process that is started. There  are
       no  restrictions	 on  the functions a service may provide. The SAF con‐
       sists of a controlling process, the service  access  controller	(SAC),
       and  two	 administrative levels corresponding to two levels in the sup‐
       porting directory structure. The top administrative level is  concerned
       with port monitor administration, the lower level with service adminis‐
       tration. The SAC is documented in the sac(1M) man page. The administra‐
       tive  levels  and  associated  utilities	 are  documented in the System
       Administration Guide - Volume II. The  requirements  for	 writing  port
       monitors and the functions a port monitor must perform to run under the
       SAF and the SAC are documented here.

   Port Monitors
       A port monitor is a process that is responsible for monitoring a set of
       homogeneous,  incoming  ports on a machine. A port monitor's major pur‐
       pose is to detect incoming service requests and to dispatch them appro‐
       priately.

       A port is an externally seen access point on a system. A port may be an
       address on a network (TSAP or PSAP),  a	hardwired  terminal  line,  an
       incoming	 phone line, etc. The definition of what constitutes a port is
       strictly a function of the port monitor itself.

       A port monitor performs certain basic  functions.  Some	of  these  are
       required to conform to the SAF; others may be specified by the require‐
       ments and design of the port monitor itself.  Port  monitors  have  two
       main  functions: managing ports and monitoring ports for indications of
       activity.

       Port Management	      The first function of a port monitor is to  man‐
			      age  a port. The actual details of how a port is
			      managed are defined by the  person  who  defines
			      the   port   monitor.  A	port  monitor  is  not
			      restricted to handling a	single	port;  it  may
			      handle multiple ports simultaneously.

			      Some examples of port management are setting the
			      line speed on incoming phone connections,	 bind‐
			      ing an appropriate network address, reinitializ‐
			      ing the port when the service  terminates,  out‐
			      putting a prompt, etc.

       Activity Monitoring    The second function of a port monitor is to mon‐
			      itor the port or ports for which it is responsi‐
			      ble  for	indications  of activity. Two types of
			      activity may be detected.

			      The first is an indication to the	 port  monitor
			      to   take	 some  port  monitor-specific  action.
			      Pressing the break key to indicate that the line
			      speed  should  be cycled is an example of a port
			      monitor activity. Not all port monitors need  to
			      recognize	 and  respond to the same indications.
			      The indication used to attract the attention  of
			      the  port	 monitor  is defined by the person who
			      defines the port monitor.

			      The second is an incoming service request.  When
			      a	 service  request  is received, a port monitor
			      must be able to determine which service is being
			      requested	 from the port on which the request is
			      received. The same service may be	 available  on
			      more than one port.

   Other Port Monitor Functions
       This section briefly describes other port monitor functions.

       Restricting Access to the System

	   A  port monitor must be able to restrict access to the system with‐
	   out disturbing services that are still  running.  In	 order	to  do
	   this, a port monitor must maintain two internal states: enabled and
	   disabled. The port monitor starts in the  state  indicated  by  the
	   ISTATE  environment	variable  provided by the sac. See sac(1M) for
	   details. Enabling or disabling a port monitor affects all ports for
	   which the port monitor is responsible. If a port monitor is respon‐
	   sible for a single port, only that port will be affected. If a port
	   monitor is responsible for multiple ports, the entire collection of
	   ports will be affected. Enabling or disabling a port monitor	 is  a
	   dynamic  operation: it causes the port monitor to change its inter‐
	   nal state. The effect does not persist across  new  invocations  of
	   the	port  monitor.	Enabling or disabling an individual port, how‐
	   ever, is a static operation: it causes a change to  an  administra‐
	   tive	 file. The effect of this change will persist across new invo‐
	   cations of the port monitor.

       Creating utmpx Entries

	   Port monitors are responsible for creating utmpx entries  with  the
	   type	 field	set  to	 USER_PROCESS for services they start. If this
	   action has been specified, by using the -fu	option	in  the	 pmadm
	   command  line  that	added  the service, these utmpx entries may in
	   turn be modified by the service. When the service  terminates,  the
	   utmpx entry must be set to DEAD_PROCESS.

       Port Monitor Process IDs and Lock Files

	   When	 a  port  monitor starts, it writes its process id into a file
	   named _pid in the current directory and places an advisory lock  on
	   the file.

       Changing the Service Environment: Running

	   doconfig(3NSL)  Before  invoking the service designated in the port
	   monitor administrative file, _pmtab, a port	monitor	 must  arrange
	   for	the per-service configuration script to be run, if one exists,
	   by calling the library function doconfig(3NSL).  Because  the  per-
	   service   configuration   script   may  specify  the	 execution  of
	   restricted commands, as well as for other  security	reasons,  port
	   monitors are invoked with root permissions. The details of how ser‐
	   vices are invoked are specified by the person who defines the  port
	   monitor.

       Terminating a Port Monitor

	   A  port  monitor must terminate itself gracefully on receipt of the
	   signal SIGTERM. The termination sequence is the following:

	       1.     The port monitor enters the stopping state;  no  further
		      service requests are accepted.

	       2.     Any  attempt  to	re-enable  the	port  monitor  will be
		      ignored.

	       3.     The port monitor yields control of all ports  for	 which
		      it is responsible. It must be possible for a new instan‐
		      tiation of the port monitor to start correctly  while  a
		      previous instantiation is stopping.

	       4.     The  advisory  lock  on the process id file is released.
		      Once this lock is released, the contents of the  process
		      id  file	are undefined and a new invocation of the port
		      monitor may be started.

   SAF Files
       This section briefly covers the files used by the SAF.

       The Port Monitor Administrative File

	   A port monitor's current directory contains an administrative  file
	   named _pmtab; _pmtab is maintained by the pmadm command in conjunc‐
	   tion with a port monitor-specific administrative command.

	   The port monitor administrative command for a listen	 port  monitor
	   is nlsadmin(1M); the port monitor administrative command for ttymon
	   is ttyadm(1M). Any port monitor written by a user must be  provided
	   with	 an  administrative  command  specific to that port monitor to
	   perform similar functions.

       Per-Service Configuration Files

	   A port monitor's current directory also  contains  the  per-service
	   configuration  scripts, if they exist. The names of the per-service
	   configuration scripts correspond to the service tags in the	_pmtab
	   file.

       Private Port Monitor Files

	   A   port   monitor  may  create  private  files  in	the  directory
	   /var/saf/tag, where tag is the name of the port  monitor.  Examples
	   of private files are log files or temporary files.

   The SAC/Port Monitor Interface
       The  SAC	 creates  two  environment  variables for each port monitor it
       starts:PMTAG and ISTATE.

       This variable is set to a unique port monitor tag by the SAC. The  port
       monitor	uses  this tag to identify itself in response to sac messages.
       ISTATE is used to indicate to the port monitor what its initial	inter‐
       nal  state should be. ISTATE is set to "enabled" or "disabled" to indi‐
       cate that the port monitor is to start in the enabled or disabled state
       respectively.

       The  SAC	 performs a periodic sanity poll of the port monitors. The SAC
       communicates with port monitors through FIFOs. A	 port  monitor	should
       open  _pmpipe,  in  the current directory, to receive messages from the
       SAC and ../_sacpipe to send return messages to the SAC.

   Message Formats
       This section describes the messages that may be sent from the SAC to  a
       port  monitor  (sac messages), and from a port monitor to the SAC (port
       monitor messages). These messages are sent through FIFOs and are in the
       form of C structures.

       sac Messages    The  format  of messages from the SAC is defined by the
		       structure sacmsg:

			 struct sacmsg
			 {
			      int sc_size; /* size of optional data portion */
			      char sc_type; /* type of message */
			 };

       The SAC may send four types of messages to port monitors. The  type  of
       message	is indicated by setting the sc_type field of the sacmsg struc‐
       ture to one of the following:

       SC_STATUS      status request

       SC_ENABLE      enable message

       SC_DISABLE     disable message

       SC_READDB      message indicating that the port monitor's  _pmtab  file
		      should be read

       The  sc_size  field indicates the size of the optional data part of the
       message. See "Message Classes." For Solaris, sc_size should  always  be
       set to 0. A port monitor must respond to every message sent by the sac.

   Port Monitor Messages
       The format of messages from a port monitor to the SAC is defined by the
       structure pmmsg:

	 struct pmmsg {
	      char pm_type;		   /* type of message */
	      unchar_t pm_state;	   /* current state of port monitor */
	      char pm_maxclass;		   /* maximum message class this port
					       monitor understands */
	      char pm_tag[PMTAGSIZE + 1];  /* port monitor's tag */
	      int pm_size;		   /* size of optional data portion */
	 };

       Port monitors may send two types of messages to the SAC.	 The  type  of
       message	is  indicated by setting the pm_type field of the pmmsg struc‐
       ture to one of the following:

       PM_STATUS     state information

       PM_UNKNOWN    negative acknowledgment

       For both types of messages, the pm_tag field is set to the  port	 moni‐
       tor's  tag  and the pm_state field is set to the port monitor's current
       state. Valid states are:

       PM_STARTING    starting

       PM_ENABLED     enabled

       PM_DISABLED    disabled

       PM_STOPPING    stopping

       The current state reflects any changes caused by the last message  from
       the  SAC. The status message is the normal return message. The negative
       acknowledgment should be sent only when the  message  received  is  not
       understood. pm_size indicates the size of the optional data part of the
       message. pm_maxclass is used to specify a message class. Both are  dis‐
       cussed under "Message Classes." In Solaris, always set pm_maxclass to 1
       and sc_size to 0. Port monitors may never initiate messages;  they  may
       only respond to messages that they receive.

   Message Classes
       The  concept of message class has been included to accommodate possible
       SAF extensions. The messages described above are all class 1  messages.
       None  of these messages contains a variable data portion; all pertinent
       information is contained in the message header.	If  new	 messages  are
       added to the protocol, they will be defined as new message classes (for
       example, class 2). The first message the SAC sends to  a	 port  monitor
       will  always  be a class 1 message. Since all port monitors, by defini‐
       tion, understand class 1 messages, the first message the SAC  sends  is
       guaranteed to be understood. In its response to the SAC, the port moni‐
       tor sets the pm_maxclass field to the maximum message class number  for
       that  port  monitor.  The  SAC will not send messages to a port monitor
       from a class with a  larger  number  than  the  value  of  pm_maxclass.
       Requests	 that require messages of a higher class than the port monitor
       can understand will fail. For Solaris, always set pm_maxclass to 1.

       For any given port monitor, messages of class pm_maxclass and  messages
       of  all	classes with values lower than pm_maxclass are valid. Thus, if
       the pm_maxclass field is set to 3, the port  monitor  understands  mes‐
       sages  of classes 1, 2, and 3. Port monitors may not generate messages;
       they may only respond to messages. A port monitor's response must be of
       the  same class as the originating message. Since only the SAC can gen‐
       erate messages, this protocol will function even if the port monitor is
       capable	of  dealing  with  messages of a higher class than the SAC can
       generate. pm_size (an element of the pmmsg structure) and  sc_size  (an
       element of the sacmsg structure) indicate the size of the optional data
       part of the message. The format of this part of the  message  is	 unde‐
       fined.  Its definition is inherent in the type of message. For Solaris,
       always set both sc_size and pm_size to 0.

   Administrative Interface
       This section discusses the port monitor administrative files  available
       under the SAC.

   The SAC Administrative File _sactab
       The  service  access controller's administrative file contains informa‐
       tion about all the port monitors for which the SAC is responsible. This
       file  exists on the delivered system. Initially, it is empty except for
       a single comment line that contains the version number of the SAC. Port
       monitors	 are added to the system by making entries in the SAC's admin‐
       istrative file. These entries should be made using  the	administrative
       command	sacadm(1M) with a -a option. sacadm(1M) is also used to remove
       entries from the SAC's administrative file. Each	 entry	in  the	 SAC's
       administrative file contains the following information.

       PMTAG	  A  unique tag that identifies a particular port monitor. The
		  system administrator is responsible for naming a port	 moni‐
		  tor.	This  tag is then used by the SAC to identify the port
		  monitor for all administrative purposes. PMTAG  may  consist
		  of up to 14 alphanumeric characters.

       PMTYPE	  The type of the port monitor. In addition to its unique tag,
		  each port monitor has a type designator. The type designator
		  identifies a group of port monitors that are different invo‐
		  cations of the same entity. ttymon and listen	 are  examples
		  of  valid port monitor types. The type designator is used to
		  facilitate the administration of groups of related port mon‐
		  itors.  Without  a type designator, the system administrator
		  has no way of knowing which port monitor tags correspond  to
		  port	monitors of the same type. PMTYPE may consist of up to
		  14 alphanumeric characters.

       FLGS	  The flags that are currently defined are:

		  d    When started, do not enable the port monitor.

		  x    Do not start the port monitor.

		  If no flag is specified, the default	action	is  taken.  By
		  default a port monitor is started and enabled.

       RCNT	  The  number  of  times  a port monitor may fail before being
		  placed in a failed state. Once a  port  monitor  enters  the
		  failed state, the SAC will not try to restart it. If a count
		  is not specified when the entry is created,  this  field  is
		  set to 0. A restart count of 0 indicates that the port moni‐
		  tor is not to be restarted when it fails.

       COMMAND	  A string representing the command that will start  the  port
		  monitor.  The	 first	component  of  the string, the command
		  itself, must be a full path name.

   The Port Monitor Administrative File _pmtab
       Each port monitor will have two directories for its exclusive use.  The
       current	directory will contain files defined by the SAF (_pmtab, _pid)
       and the per-service configuration scripts, if they exist. The directory
       /var/saf/pmtag,	where  pmtag is the tag of the port monitor, is avail‐
       able for the port monitor's private files. Each port  monitor  has  its
       own  administrative  file. The pmadm(1M) command should be used to add,
       remove, or modify service entries in this file. Each time a  change  is
       made using pmadm(1M), the corresponding port monitor rereads its admin‐
       istrative file. Each entry in  a	 port  monitor's  administrative  file
       defines how the port monitor treats a specific port and what service is
       to be invoked on that port. Some fields must be present for  all	 types
       of port monitors. Each entry must include a service tag to identify the
       service uniquely and an identity to be assigned to the service when  it
       is started (for example, root).

       The combination of a service tag and a port monitor tag uniquely define
       an instance of a service. The same service tag may be used to  identify
       a  service under a different port monitor. The record must also contain
       port monitor specific data (for example, for  a	ttymon	port  monitor,
       this  will  include  the	 prompt string which is meaningful to ttymon).
       Each type of port monitor must provide a command that takes the	neces‐
       sary  port monitor-specific data as arguments and outputs these data in
       a form suitable for storage in the file. The  ttyadm(1M)	 command  does
       this for ttymon and nlsadmin(1M) does it for listen. For a user-defined
       port monitor, a similar administrative command must also	 be  supplied.
       Each  service  entry  in the port monitor administrative file must have
       the following format and contain the information listed below:

	 svctag:flgs:id:reserved:reserved:reserved:pmspecific# comment

       SVCTAG is a unique tag that identifies a service. This  tag  is	unique
       only for the port monitor through which the service is available. Other
       port monitors may offer the same or other services with the same tag. A
       service	requires both a port monitor tag and a service tag to identify
       it uniquely. SVCTAG may consist of up to	 14  alphanumeric  characters.
       The service entries are defined as:

       FLGS	     Flags  with  the  following  meanings  may	 currently  be
		     included in this field:

		     x	  Do not enable this port.  By	default	 the  port  is
			  enabled.

		     u	  Create a utmpx entry for this service. By    default
			  no utmpx entry is created for the	service.

       ID	     The identity under which the service is  to  be  started.
		     The  identity  has the form of a login name as it appears
		     in /etc/passwd.

       PMSPECIFIC    Examples of port monitor information are  addresses,  the
		     name  of  a process to execute, or the name of a STREAMS-
		     based pipe to pass a connection through. This information
		     will  vary	 to  meet  the needs of each different type of
		     port monitor.

       COMMENT	     A comment associated with the service entry.  Port	 moni‐
		     tors  may ignore the u flag if creating a utmpx entry for
		     the service is not appropriate to the manner in which the
		     service  is  to  be  invoked. Some services may not start
		     properly unless utmpx entries have been created for  them
		     (for  example,  login).  Each port monitor administrative
		     file must contain one special comment of the form:

		     # VERSION=value

		     where value is an integer that represents the port	 moni‐
		     tor's version number. The version number defines the for‐
		     mat of the port monitor administrative file. This comment
		     line  is  created	automatically  when  a port monitor is
		     added to the system. It appears  on  a  line  by  itself,
		     before the service entries.

   Monitor-Specific Administrative Command
       Previously,  two pieces of information included in the _pmtab file were
       described: the port monitor's version number and the port monitor  part
       of  the	service	 entries in the port monitor's _pmtab file. When a new
       port monitor is added, the version number must be  known	 so  that  the
       _pmtab  file can be correctly initialized. When a new service is added,
       the port monitor part of the _pmtab entry must be formatted  correctly.
       Each  port monitor must have an administrative command to perform these
       two tasks. The person who defines the port  monitor  must  also	define
       such  an administrative command and its input options. When the command
       is invoked with these options, the information required	for  the  port
       monitor	part  of  the  service	entry  must be correctly formatted for
       inclusion in the port monitor's _pmtab file and must be written to  the
       standard	 output.  To  request  the  version number the command must be
       invoked with a -V option; when it is invoked in this way, the port mon‐
       itor's  current	version number must be written to the standard output.
       If the command fails for any reason during the execution of  either  of
       these tasks, no data should be written to standard output.

   The Port Monitor/Service Interface
       The interface between a port monitor and a service is determined solely
       by the service. Two mechanisms for invoking  a  service	are  presented
       here as examples.

       New Service Invocations

	   The first interface is for services that are started anew with each
	   request. This interface requires the port monitor to first  fork(2)
	   a  child  process.  The child will eventually become the designated
	   service by performing an exec(1). Before the exec(1)	 happens,  the
	   port	 monitor  may take some port monitor-specific action; however,
	   one action that must occur is the interpretation of the per-service
	   configuration  script,  if  one is present. This is done by calling
	   the library routine doconfig(3NSL).

       Standing Service Invocations

	   The second interface	 is  for  invocations  of  services  that  are
	   actively  running.  To  use this interface, a service must have one
	   end of a stream pipe open and be prepared  to  receive  connections
	   through it.

   Port Monitor Requirements
       To  implement a port monitor, several generic requirements must be met.
       This section summarizes these requirements. In  addition	 to  the  port
       monitor itself, an administrative command must be supplied.

       Initial Environment    When  a  port  monitor is started, it expects an
			      initial execution environment in which:

				  o	 It has no file descriptors open

				  o	 It cannot be a process group leader

				  o	 It has an entry in /etc/utmpx of type
					 LOGIN_PROCESS

				  o	 An  environment  variable, ISTATE, is
					 set to	 "enabled"  or	"disabled"  to
					 indicate  the	port monitor's correct
					 initial state

				  o	 An environment	 variable,  PMTAG,  is
					 set  to  the  port monitor's assigned
					 tag

				  o	 The directory that contains the  port
					 monitor's administrative files is its
					 current directory

				  o	 pThe port monitor is able  to	create
					 private   files   in	the  directory
					 /var/saf/tag, where tag is  the  port
					 monitor's tag

				  o	 The port monitor is running with user
					 id 0 (root)

       Important Files	      Relative to its current directory, the following
			      key files exist for a port monitor.

			      _config	       The  port  monitor's configura‐
					       tion script. The	 port  monitor
					       configuration  script is run by
					       the SAC. The SAC is started  by
					       init(1M)	 as  a	result	of  an
					       entry  in   /etc/inittab	  that
					       calls sac(1M).

			      _pid	       The  file  into	which the port
					       monitor writes its process id.

			      _pmtab	       The port monitor's  administra‐
					       tive  file.  This file contains
					       information about the ports and
					       services	 for  which  the  port
					       monitor is responsible.

			      _pmpipe	       The FIFO through which the port
					       monitor	will  receive messages
					       from the SAC.

			      svctag	       The  per-service	 configuration
					       script for the service with the
					       tag svctag.

			      ../_sacpipe      The FIFO through which the port
					       monitor	will  send messages to
					       sac(1M).

   Port Monitor Responsibilities
       A port monitor is responsible for performing  the  following  tasks  in
       addition to its port monitor function:

	   o	  Write	 its  process id into the file _pid and place an advi‐
		  sory lock on the file

	   o	  Terminate gracefully on receipt of the signal SIGTERM

	   o	  Follow the protocol for message exchange with the SAC

       A port monitor must perform the following tasks during service  invoca‐
       tion:

	   o	  Create a utmpx entry if the requested service has the u flag
		  set in _pmtab

	   o	  Port monitors may ignore this flag if creating a utmpx entry
		  for the service does not make sense because of the manner in
		  which the service is to be invoked. On the other hand,  some
		  services  may	 not  start properly unless utmpx entries have
		  been created for them.

	   o	  Interpret  the  per-service  configuration  script  for  the
		  requested  service,  if  it  exists,	by  calling the docon‐
		  fig(3NSL) library routine

   Configuration Files and Scripts
       The library routine doconfig(3NSL), defined  in	libnsl.so,  interprets
       the  configuration  scripts  contained in the files /etc/saf/_sysconfig
       (the per-system configuration file), and	 /etc/saf/pmtag/_config	 (per-
       port  monitor  configuration files); and in /etc/saf/pmtag/svctag (per-
       service configuration files). Its syntax is:

	 #include <sac.h>
	      int doconfig (int fd, char *script, long rflag);

       script is the name of the configuration script; fd is a file descriptor
       that  designates the stream to which stream manipulation operations are
       to be applied; rflag is a bitmask that  indicates  the  mode  in	 which
       script is to be interpreted. rflag may take two values, NORUN and NOAS‐
       SIGN, which may be or'd. If rflag is zero, all commands in the configu‐
       ration script are eligible to be interpreted. If rflag has the NOASSIGN
       bit set, the assign command is considered illegal and will generate  an
       error  return. If rflag has the NORUN bit set, the run and runwait com‐
       mands are considered illegal and will generate error returns. If a com‐
       mand  in	 the  script fails, the interpretation of the script ceases at
       that point and a positive integer is returned;  this  number  indicates
       which  line  in the script failed. If a system error occurs, a value of
       −1 is returned. If a script fails, the process  whose  environment  was
       being established should not be started. In the example, doconfig(3NSL)
       is used to interpret a per-service configuration script.

	 ...
		   if ((i = doconfig (fd, svctag, 0)) != 0){
		   error ("doconfig failed on line %d of script %s",i,svctag);
	      }

       The Per-System Configuration File

	   The per-system configuration file, /etc/saf/_sysconfig,  is	deliv‐
	   ered	 empty.	 It  may  be used to customize the environment for all
	   services on the system by writing a command script  in  the	inter‐
	   preted language described in this chapter and on the doconfig(3NSL)
	   manpage. When the SAC is started, it calls the doconfig(3NSL) func‐
	   tion	 to  interpret the per-system configuration script. The SAC is
	   started when the system enters multiuser mode.

       Per-Port Monitor Configuration Files

	   Per-port monitor configuration  scripts  (  /etc/saf/pmtag/_config)
	   are	optional. They allow the user to customize the environment for
	   any given port monitor and for  the	services  that	are  available
	   through  the ports for which that port monitor is responsible. Per-
	   port monitor configuration scripts are written in the same language
	   used	 for  per-system  configuration	 scripts. The per-port monitor
	   configuration script	 is  interpreted  when	the  port  monitor  is
	   started.  The  port monitor is started by the SAC after the SAC has
	   itself been started and after it  has  run  its  own	 configuration
	   script,  /etc/saf/_sysconfig.  The  per-port	 monitor configuration
	   script may override defaults provided by the per-system  configura‐
	   tion script.

       Per-Service Configuration Files

	   Per-service	configuration  files  allow  the user to customize the
	   environment for a specific service.	For  example,  a  service  may
	   require  special  privileges	 that are not available to the general
	   user. Using the language described in the  doconfig(3NSL)  manpage,
	   you can write a script that will grant or limit such special privi‐
	   leges to a particular service offered  through  a  particular  port
	   monitor.  The  per-service configuration may override defaults pro‐
	   vided by higher-level configuration scripts. For example, the  per-
	   service  configuration  script may specify a set of STREAMS modules
	   other than the default set.

   The Configuration Language
       The language in which configuration scripts are written consists	 of  a
       sequence of commands, each of which is interpreted separately. The fol‐
       lowing reserved keywords are defined: assign, push, pop,	 runwait,  and
       run.  The  comment  character is #. Blank lines are not significant. No
       line in a command script may exceed 1024 characters.

       assign variable=value

	   Used to define environment variables; variable is the name  of  the
	   environment	variable  and value is the value to be assigned to it.
	   The value assigned must be a string constant; no form of  parameter
	   substitution	 is  available. value may be quoted. The quoting rules
	   are those used by the shell	for  defining  environment  variables.
	   assign  will fail if space cannot be allocated for the new variable
	   or if any part of the specification is invalid.

       push module1[,module2, module3, . . .]

	   Used to push STREAMS modules onto the stream designated by fd; mod‐
	   ule1	 is  the name of the first module to be pushed, module2 is the
	   name of the second module to be pushed, and so on. The command will
	   fail if any of the named modules cannot be pushed. If a module can‐
	   not be pushed, the subsequent modules on the same command line will
	   be  ignored	and  modules  that  have  already  been pushed will be
	   popped.

       pop [module]

	   Used to pop STREAMS modules off the designated stream.  If  pop  is
	   invoked  with no arguments, the top module on the stream is popped.
	   If an argument is given, modules will be popped one at a time until
	   the	named  module is at the top of the stream. If the named module
	   is not on the designated stream, the stream is left as it  was  and
	   the	command	 fails. If module is the special keyword ALL, then all
	   modules on the stream will be popped. Only modules above  the  top‐
	   most driver are affected.

       runwait command

	   The	runwait	 command  runs a command and waits for it to complete;
	   command is the path name of the command to be run. The  command  is
	   run with /bin/sh -c prepended to it; shell scripts may thus be exe‐
	   cuted from configuration scripts. The runwait command will fail  if
	   command  cannot be found or cannot be executed, or if command exits
	   with a nonzero status.

       run command

	   The run command is identical to runwait except  that	 it  does  not
	   wait	 for command to complete; command is the path name of the com‐
	   mand to be run.  run will not fail unless it is  unable  to	create
	   achild  process to execute the command. Although they are syntacti‐
	   cally indistinguishable, some of the commands available to run  and
	   runwait  are	 interpreter  built-in commands. Interpreter built-ins
	   are used when it is necessary to  alter  the	 state	of  a  process
	   within the context of that process. The doconfig interpreter built-
	   in commands are similar to the shell	 special  commands  and,  like
	   these,  they	 do  not  spawn another process for execution. See the
	   sh(1) man page. The	initial	 set  of  built-in  commands  is:  cd,
	   ulimit, umask.

   Sample Port Monitor Code
       This  example  shows  an	 example  of a "null" port monitor that simply
       responds to messages from the SAC.

	 # include <stdlib.h>
	 # include <stdio.h>
	 # include <unistd.h>
	 # include <fcntl.h>
	 # include <signal.h>
	 # include <sac.h>

	 char Scratch[BUFSIZ]; /* scratch buffer */
	 char Tag[PMTAGSIZE + 1]; /* port monitor's tag */
	 FILE *Fp; /* file pointer for log file */
	 FILE *Tfp; /* file pointer for pid file */
	 char State; /* portmonitor's current state*/

	 main(argc, argv)
	      int argc;
	      char *argv[];
	 {
	      char *istate;
	      strcpy(Tag, getenv("PMTAG"));
	 /*
	  * open up a log file in port monitor's private directory
	  */
	      sprintf(Scratch, "/var/saf/%s/log", Tag);
	      Fp = fopen(Scratch, "a+");
	      if (Fp == (FILE *)NULL)
		   exit(1);
	      log(Fp, "starting");
	 /*
	  * retrieve initial state (either "enabled" or "disabled") and set
	  * State accordingly
	  */
	      istate = getenv("ISTATE");
	      sprintf(Scratch, "ISTATE is %s", istate);
	      log(Fp, Scratch);
	      if (!strcmp(istate, "enabled"))
		   State = PM_ENABLED;
	      else if (!strcmp(istate, "disabled"))
		   State = PM_DISABLED;
	      else {
		   log(Fp, "invalid initial state");
		   exit(1);
	      }
	      sprintf(Scratch, "PMTAG is %s", Tag);
	      log(Fp, Scratch);
	 /*
	  * set up pid file and lock it to indicate that we are active
	  */
	      Tfp = fopen("_pid", "w");
	      if (Tfp == (FILE *)NULL) {
		   log(Fp, "couldn't open pid file");
		   exit(1);
	      }
	      if (lockf(fileno(Tfp), F_TEST, 0) < 0) {
		   log(Fp, "pid file already locked");
		   exit(1);
	      }

	      log(Fp, "locking file");
	      if (lockf(fileno(Tfp), F_LOCK, 0) < 0) {
		   log(Fp, "lock failed");
		   exit(1);
	      }
	      fprintf(Tfp, "%d", getpid());
	      fflush(Tfp);

	 /*
	  * handle poll messages from the sac ... this function never returns
	  */
	      handlepoll();
	      pause();
	      fclose(Tfp);
	      fclose(Fp);
	 }

	 handlepoll()
	 {
	      int pfd; /* file descriptor for incoming pipe */
	      int sfd; /* file descriptor for outgoing pipe */
	      struct sacmsg sacmsg; /* incoming message */
	      struct pmmsg pmmsg; /* outgoing message */
	 /*
	  * open pipe for incoming messages from the sac
	  */
	      pfd = open("_pmpipe", O_RDONLY|O_NONBLOCK);
	      if (pfd < 0) {
		   log(Fp, "_pmpipe open failed");
		   exit(1);
	      }
	 /*
	  * open pipe for outgoing messages to the sac
	  */
	      sfd = open("../_sacpipe", O_WRONLY);
	      if (sfd < 0) {
		   log(Fp, "_sacpipe open failed");
		   exit(1);
	      }
	 /*
	  * start to build a return message; we only support class 1 messages
	  */
	      strcpy(pmmsg.pm_tag, Tag);
	      pmmsg.pm_size = 0;
	      pmmsg.pm_maxclass = 1;
	 /*
	  * keep responding to messages from the sac
	  */
	      for (;;) {
		   if (read(pfd, &sacmsg, sizeof(sacmsg)) != sizeof(sacmsg)) {
			log(Fp, "_pmpipe read failed");
			exit(1);
		   }
	 /*
	  * determine the message type and respond appropriately
	  */
		   switch (sacmsg.sc_type) {
			case SC_STATUS:
			     log(Fp, "Got SC_STATUS message");
			     pmmsg.pm_type = PM_STATUS;
			     pmmsg.pm_state = State;
			     break;
			case SC_ENABLE:
			     /*note internal state change below*/
			     log(Fp, "Got SC_ENABLE message");
			     pmmsg.pm_type = PM_STATUS;
			     State = PM_ENABLED;
			     pmmsg.pm_state = State;
			     break;
			case SC_DISABLE:
			     /*note internal state change below*/
			     log(Fp, "Got SC_DISABLE message");
			     pmmsg.pm_type = PM_STATUS;
			     State = PM_DISABLED;
			     pmmsg.pm_state = State;
			     break;
			case SC_READDB:
			     /*
			      * if this were a fully functional port
			      * monitor it would read _pmtab here
			      * and take appropriate action
			      */
			     log(Fp, "Got SC_READDB message");
			     pmmsg.pm_type = PM_STATUS;
			     pmmsg.pm_state = State;
			     break;
			default:
			     sprintf(Scratch, "Got unknown message <%d>",
			     sacmsg.sc_type);
			     log(Fp, Scratch);
			     pmmsg.pm_type = PM_UNKNOWN;
			     pmmsg.pm_state = State;
			     break;
		   }
	 /*
	  * send back a response to the poll
	  * indicating current state
	  */
		   if (write(sfd, &pmmsg, sizeof(pmmsg)) != sizeof(pmmsg))
			log(Fp, "sanity response failed");
	      }
	 }
	 /*
	  * general logging function
	  */
	 log(fp, msg)
	      FILE *fp;
	      char *msg;
	 {
	      fprintf(fp, "%d; %s\n", getpid(), msg);
	      fflush(fp);
	 }

   The sac.h Header File
       The following example shows the sac.h header file.

	 /* length in bytes of a utmpx id */
	 # define IDLEN 4
	 /* wild character for utmpx ids */
	 # define SC_WILDC 0xff
	 /* max len in bytes for port monitor tag */
	 # define PMTAGSIZE 14
	 /*
	  * values for rflag in doconfig()
	  */
	 /* don't allow assign operations */
	 # define NOASSIGN 0x1
	 /* don't allow run or runwait operations */
	 # define NORUN 0x2
	 /*
	  * message to SAC (header only). This header is forever fixed. The
	  * size field (pm_size) defines the size of the data portion of the
	  * message, which follows the header. The form of this optional data
	  * portion is defined strictly by the message type (pm_type).
	  */
	 struct pmmsg {
	      char pm_type;		  /* type of message */
	      unchar_t pm_state;	    /* current state of pm */
	      char pm_maxclass;		  /* max message class this port monitor
						  understands */
	      char pm_tag[PMTAGSIZE + 1]; /* pm's tag */
	      int pm_size;		  /* size of opt data portion */
	 };
	 /*
	  * pm_type values
	  */
	 # define PM_STATUS 1 /* status response */
	 # define PM_UNKNOWN 2 /* unknown message was received */
	 /*
	  * pm_state values
	  */
	 /*
	  * Class 1 responses
	  */
	 # define PM_STARTING 1	  /* monitor in starting state */
	 # define PM_ENABLED 2	  /* monitor in enabled state */
	 # define PM_DISABLED 3	  /* monitor in disabled state */
	 # define PM_STOPPING 4	  /* monitor in stopping state */
	 /*
	  * message to port monitor
	  */
	 struct sacmsg {
	      int sc_size;	   /* size of optional data portion */
	      char sc_type;	   /* type of message */
	 };
	 /*
	  * sc_type values
	  * These represent commands that the SAC sends to a port monitor.
	  * These commands are divided into "classes" for extensibility. Each
	  * subsequent "class" is a superset of the previous "classes" plus
	  * the new commands defined within that "class". The header for all
	  * commands is identical; however, a command may be defined such that
	  * an optional data portion may be sent in addition to the header.
	  * The format of this optional data piece is self-defining based on
	  * the command. The first message sent by the SAC
	  * will always be a class 1 message. The port monitor response
	  * indicates the maximum class that it is able to understand. Another
	  * note is that port monitors should only respond to a message with
	  * an equivalent class response (i.e. a class 1 command causes a
	  * class 1 response).
	  */
	 /*
	  * Class 1 commands (currently, there are only class 1 commands)
	  */
	 # define SC_STATUS 1	 /* status request *
	 # define SC_ENABLE 2	 /* enable request */
	 # define SC_DISABLE 3	 /* disable request */
	 # define SC_READDB 4	 /* read pmtab request */
	 /*
	  * `errno' values for Saferrno, note that Saferrno is used by both
	  * pmadm and sacadm and these values are shared between them
	  */
	 # define E_BADARGS 1	/* bad args/ill-formed cmd line */
	 # define E_NOPRIV 2	/* user not priv for operation */
	 # define E_SAFERR 3	/* generic SAF error */
	 # define E_SYSERR 4	/* system error */
	 # define E_NOEXIST 5	/* invalid specification */
	 # define E_DUP 6	/* entry already exists */
	 # define E_PMRUN 7	/* port monitor is running */
	 # define E_PMNOTRUN 8	/* port monitor is not running */
	 # define E_RECOVER 9
	    /* in recovery */

   Directory Structure
       This section gives a description of the SAF files and directories.

       /etc/saf/_sysconfig	   The per-system configuration script.

       /etc/saf/_sactab		   The	SAC's  administrative  file.  Contains
				   information	about  the  port  monitors for
				   which the SAC is responsible.

       /etc/saf/pmtag		   The home directory for port monitor pmtag.

       /etc/saf/pmtag/_config	   The per-port monitor	 configuration	script
				   for port monitor pmtag.

       /etc/saf/pmtag/_pmtab	   Port	 monitor  pmtag's administrative file.
				   Contains information about the services for
				   which pmtag is responsible.

       /etc/saf/pmtag/svctag	   The	file in which the per-service configu‐
				   ration script for service svctag (available
				   through port monitor pmtag) is placed.

       /etc/saf/pmtag/_pid	   The file in which a port monitor writes its
				   process id in  the  current	directory  and
				   places an advisory lock on the file.

       /etc/saf/ pmtag /_pmpipe	   The file in which the port monitor receives
				   messages from the SAC and  ../_sacpipe  and
				   sends return messages to the SAC.

       /var/saf/_log		   The SAC's log file.

       /var/saf/pmtag		   The	directory  for	files  created by port
				   monitor pmtag, for example its log file.

LIST OF COMMANDS
       The following administrative commands relate to SAF.

       sacadm(1M)    port monitor administrative command

       pmadm(1M)     service administration command

ATTRIBUTES
       See attributes(5) for descriptions of the following attributes:

       ┌─────────────────────────────┬─────────────────────────────┐
       │      ATTRIBUTE TYPE	     │	    ATTRIBUTE VALUE	   │
       ├─────────────────────────────┼─────────────────────────────┤
       │Availability		     │SUNWcsr			   │
       └─────────────────────────────┴─────────────────────────────┘

SEE ALSO
       exec(1), sh(1), init(1M), nlsadmin(1M), pmadm(1M), sac(1M), sacadm(1M),
       ttyadm(1M), fork(2), doconfig(3NSL), attributes(5)

SunOS 5.10			  30 Jul1998			       saf(1M)
[top]

List of man pages available for SunOS

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net