\subsection{The Connection Object}
The connection object is a major player in the SICS world. The connection
object represents an active connection between the SICS server and a client.
There will be one connection object for each client connection. A lot of
stuff is associated with a client connection:
\begin{itemize}
\item A task. This task will read one command from the command fifo and
execute it.
\item A command fifo which will be filled by the network reader.
\item An execution context consisting of user rights for this connection
 and interrupt status. 
\item A communication channel to the client.
\item A list of log files to which all traffic on the connection will be 
logged.
\item An interface to the SICS interpreter which allows to configure 
 certain aspects of the connection and makes the connection available as
 a command.
\item A list of callbacks registered for the connection. A connection can
 be automatically notified about  changes in system state. These callbacks 
 have to be removed when the client  server connection terminates. Otherwise
 callback code would write to a dead connection causing the program to
 crash.
\end{itemize}

\subsubsection{Connection I/O}
Due to user requirements for features not considered in the design the
I/O facilities of connection have become quite involved. 

Incoming commands are printed into client log files if configured, and
into the commandlog if the connection has a privilege $\ge$ user
privilege. This is implemented in SCInvoke. Also each command is
printed to the server log. 

Output is more sophisticated. First of all there are different output
codes given as last parameter to SCWrite. The most important of these
are:
\begin{description}
\item[eError] Error messages.
\item[Warning] warnings.
\item[Value] values requested by the client.
\item[Status] status messages. 
\end{description}
Clients can choose to suppress certain types of messages in order to
reduce I/O. 

The logic is mostly implemented in the
file static function  SCNormalWrite. The follwoing conditions are
implemented: 
\begin{itemize}
\item Any output is logged to the
server log. 
\item If the privilege of the connection is $\ge$ user the
output is printed to the commandlog as well. 
\item If the command is executing as part of a Tcl--macro script
output to the socket is suppressed. The output is copied into the
interpreter for further evaluation instead. This is done in order to
prevent excessive output during macro evaluation and in order to make
SICS results available in the Tcl interpreter. However, messages of
type error or warning are printed to the socket even during macro
evaluation.
\item In the normal case the output is printed to the socket and all
log files configured for the connection.
\item As of recent the output function can be modified by setting a
new function. One sich function exists which supresses all output to
the socket. This is done in order to help when the connection gets
lost. For instance with the cron command.  
\end{itemize}  
This aspect of the connection object could do with a cleanup. A
possible cleanup path is  the implementation of the different output 
 strategies in different functions and devise a SCsetOutMode function which
switches between the various possibilities. Also, it can be argued if
the client specific log files are still needed. Then this part of the
code can be cleaned out as well.  


\subsubsection{Command Execution Path}
In the course of the SICS development the path of a command through
the system has become more complex as well. This section describes how
it works. The incoming command is collected at the socket by the
NetReaderTask. This does a little processing and checks for interrupts
issued on the connection and invokes them. But any normal command is
put into the connections Command-FIFO. Thus ends the business of the
NetReaderTask. The connections task function   SCTaskFunction is
invoked by the task manager in due time and checks for pending
commands on the command stack. If a command is pending it is taken
from the stack and executed through SCInvoke. 

\subsubsection{Execution context}
Each connection has a user right code associated with it. The there is
a second protection scheme in SICS with the token system. This system
reserves command input to a certain connection. In the connection
object this scheme requires the iGrab field which defines if this
connection may execute commands or not. This field is modified through
the tasks signal handling function. Code implementing a command may
call SCMatchRights in order to check for permission. SCMatchRights
will also send appropriate error messages. 

Errors are usually signalled by setting an interrupt code on the
connection. An additional field, iError allows to give a more detailed
error description if required. 

\subsubsection{Callbacks}
SICS can be configured to forward notifications about certain state
changes to a connection automatically. This is implemented through the
callback system. For more details see \ref{inter}. However, it is
important that any callback acting on a connection is registered with
the connection object. This allows the removal of the callback when
the connection is closed. Otherwsie the system gets filled up with
dead callbacks which usuallly cause core dumps when it is tried to
send a message to a dead connection.  


\subsubsection{The Connection Data Structure} 
Given the plethora of things to take care of, each connection is
represented by a rather large data structure.

@d condat @{
   typedef struct __SConnection {
                                  /* object basics */
                                  pObjectDescriptor pDes;
                                  char *pName;
                                  long lMagic;
                                  
                                  /* I/O control */
                                  mkChannel *pSock;
                                  FILE *pFiles[MAXLOGFILES];
                                  int iMacro;
                                  int iTelnet;
                                  int iOutput;                                
                                  int iFiles;
                                  int (*write)(struct __SConnection *pCon,
                                      char *pMessage, int iCode);
                                  mkChannel *pDataSock;
                                  char      *pDataComp;
                                  int       iDataPort;

                                  /* execution context */
                                  int eInterrupt;
                                  int iUserRights;
                                  int inUse;
                                  int iDummy;
                                  int iGrab;
                                  int iErrCode;
                                  SicsInterp *pSics;
                                  
                                  /* a FIFO */
                                  pCosta pStack;

                                  /* callback registry */
                                  int iList;
 
                                   /* Tasking Stuff */
                                   int iEnd;
                                 }SConnection;
@} 

The fields are:
\begin{description}
\item[pDes] The usual object descriptor belonging to any object within the
SICS interpreter. See \ref{inter} for details.
\item[pName] The automatically generated name of the connection object in the
 interpreter.
\item[lMagic] is a magic number used internally in order to check if
the connection object given as a parameter is valid. 

\item[pChannel] A pointer to a network channel structure. This channel
 will be used for I/O to the client. If thispointer is NULL I/O is done onto
 stdin/stdout instead.
\item[pFiles] An array of file to which all I/O on this connection will be 
 logged.
\item[iOutPut] The currently valid output mask. SICS messages are classified
into several output classes. If a message is going to be printed it must
have a output class above the one configured as the mask. This was made in
order to allow clients to suppress certain messages which are not of
interest.                                
\item[iFiles] The number of configured log files.
\item[write] a pointer to a function which does the actual writing of
a message to the connection. 
\item[iTelnet] is true when I/O is through a telnet connection.
\item[iMacro] This flag is set when the connection is executing a Tcl
script. In this mode mode all output is written into the Tcl interpreter and
not written to the client. Thus a script can execute silently. As always,
there is an exception: errors and warning will still be written to the
client.

\item[iGrab] This is 0 when the connection may execute commands. It is 1 if
another connection has grabbed the control token and commands may not be
executed. For details about the token system, see the token reference.
\item[eInterrupt] This is the current interrupt status of the connection.
\item[iUserRights] This integer denotes the user rights associated with the
connection. This value is initially deducted from the username password pair
given at login to SICS. The value can be configured otherwise afterwards.
iUserRights will be used to check at object level if a client may perform
the requested operation or not.
\item[iErrCode] is the last error code. I think this field is no longer
used.

\item[pSics] is a pointer to an SICS interpreter where to invoke commands.
\item[pStack] Is the command FIFO.
\item[iList] This is the identifier of a lld list which holds the callbacks
registered on this connection object.
\item[iEnd] iEnd is a flag which is usually 0. It is set by certain
interrupts or if the connection is broken and causes the connection task to
end and the connection data structure to be removed from the system.
\end{description}
Quite a few places in SICS refer to this data structure directly,
without a function interface. The reason for this is performance. Therefore
this data structure is made public in the conman.h file.


\subsubsection{Connection Functions}
The interface to this data structure is defined by the following functions:
@d conint @{
/*------------------------------ live & death ----------------------------*/
   SConnection *SCreateConnection(SicsInterp *pSics, mkChannel *pSock,
                                  int iUserRights);
   SConnection *SCCreateDummyConnection(SicsInterp *pSics);
   void         SCDeleteConnection(void *pVictim);
 
/*------------------------------- tasking --------------------------------*/
   int SCTaskFunction(void *pCon);
   void SCSignalFunction(void *pCon, int iSignal, void *pSigData);
/* ***************************** I/O **************************************  */
  int SCAddLogFile(SConnection *self, char *name);
  int SCDelLogFile(SConnection *pCon, int iFile);
  void SCSetOutputClass(SConnection *self, int iClass);
  int SCWrite(SConnection *self, char *pBuffer, int iOut);
  int SCRead(SConnection *self, char *pBuffer, int iBufLen);   
  int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);
  int SCSendOK(SConnection *self);
  int SCnoSock(SConnection *pCon);
  int SCWriteUUencoded(SConnection *pCon, char *pName, void *iData, int iLen);
/*************************   CallBack *********************************** */
   int SCRegister(SConnection *pCon, SicsInterp *pSics,
                            void *pInter, long lID);
   int SCUnregister(SConnection *pCon, void *pInter);
/******************************* Error **************************************/
   void SCSetInterrupt(SConnection *self, int eCode);
   int SCGetInterrupt(SConnection *self);   
   void SCSetError(SConnection *pCon, int iCode);
   int  SCGetError(SConnection *pCon); 
/****************************** Macro ***************************************/
   int SCinMacro(SConnection *pCon);
   int SCsetMacro(SConnection *pCon, int iMode);    

/* *************************** Info *************************************** */
   int SCGetRights(SConnection *self);
   int SCSetRights(SConnection *pCon, int iNew);
   int SCMatchRights(SConnection *pCon, int iCode);
   int SCGetOutClass(SConnection *self);
   int SCGetGrab(SConnection *pCon);

/* **************************** Invocation ******************************** */
   int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);
      
/*************************** User Command **********************************/
       int ConfigCon(SConnection *pCon, SicsInterp *pSics, void *pData,
                     int argc, char *argv[]);                              
       int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
                     int argc, char *argv[]);                              
           
@}
The functions in more detail:
\begin{description}
\item[SCreateConnection] creates a new connection object. Parameters to this
call are a pointer to a server data structure, a pointer to a network
connection object and the user rights to use in this connection. This
also adds a new task function for this connection to the task object.
\item[SCCreateDummyConnection] creates a dummy connection for use during
system initialisation. Printing to a socket will be suppressed for such a connection. But the output is printed to stdout.

\item[SCTaskFunction] is the task function which will be registered with the
Tasker. This function reads a new command from the command stack (if
available) and executes it in the interpreter.
\item[SCSignalFunction] is the signal function for the connection
object. This function handles interrupts and the token security
system. 
\item[SCDeleteConnection] deletes a  connection object and all its data
structures. This function will be automatically called by the tasker when
the task function returns with a 0.
\item[SCAddLogFile] configures the log file name into the connection object.
If this suceeds all I/O to the connection will be logged to this file as
well.
\item[SCSetOutputClass] sets the output class for the connection.
\item[SCGetOutClass] returns the output class of the connection.
\item[SCWrite] is the most important function of SConnection. Writes the
buffer pBuffer with output code iOut to the client. {\em All output to the
client has to be channelled through this function!} 
\item[SCRead] reads data from the client connection into the buffer pBuffer,
but maximum iBufLen bytes.
\item[SCPrompt] prompts the client for a reply. But waits only for certain
timeout period. pPrompt is the prompt for the client, pResult is the buffer
with the client reply. Maximum iLen bytes will be copied to
pResult. Returns true (1) on a successfull read, else 0 (false).
\item[SCSendOK] A short cut which sends OK to the client.
\item[SCRegister] registers a callback with the connection. Parameters are: 
 The interpreter to use, the interface with which the callback was
registered and the ID of the callback. All automatic notifications to a
client MUST be registered with this call. When the connection is deleted all
 these callbacks will be removed as well. Otherwise a core dump is bound to
happen.
\item[SCUnregister] will remove all callbacks on interface pInter for this
 connection.
\item[SCSetInterrupt] sets an interrupt on the connection.
\item[SCGetInterrupt] retrives the current interrupt status of the
connection.
\item[SCSetError] sets an error code in the connection.
\item[SCGetError] retreives the current error code on the connection.
\item[SCinMacro] returns true if the connection is executing a tcl script,
returns false otherwise.
\item[SCsetMacro]  sets the iMacro flag.
\item[SCGetRights] returns the current user rights associated with the
connection. 
\item[SCGetGrab] gets the status of the control token for this connection.
This calls returns 0 if the connection may execute commands and 1 if another
connection has the control token.
\item[SCSetRights] sets the user rights for the connection to a new value.
\item[SCMatchRights] return true (1) if the iCode matches with the user
rights of the connection, 0 (false) otherwise. SCMatchRights also checks for
the status of the control token. Suitable error messages are written to pCon
if the user rights do not match.
\item[SCInvoke] invokes pCommand in the SICS interpreter pSics for the
connection pCon. This function also prints the executed command into
logfiles and into the commandlog. 
\end{description}

@o conman.h @{
/*--------------------------------------------------------------------------
                       C O N N E C T I O N   O B J E C T

 This file defines the connection object data structure and the interface to
 this data structure. This is one of the most important SICS components.


  Substantially revised from a prior version.

  Mark Koennecke, September 1997

  copyright: see copyright.h
----------------------------------------------------------------------------*/
#ifndef SICSCONNECT
#define SICSCONNECT
#include <stdio.h>
#include "costa.h"
#include "SCinter.h"
#include "network.h"
#include "obdes.h"

#define MAXLOGFILES 10
@<condat@>
#include "nserver.h"
@<conint@>

#endif 
@}

