"Fossies" - the Fresh Open Source Software Archive

Member "citadel/docs/citadelapi.txt" (5 Jun 2021, 12556 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1  Citadel Server Extension API Documentation
    2  ---------------------------------------------
    3  
    4   This is a VERY INCOMPLETE documentation of the API for extending the
    5 Citadel server using dynamically loaded modules.  It really isn't an API at
    6 all, but rather a list of some of the functions available in the server which
    7 are likely to be of use to module writers.
    8  
    9   The current trend is to move as much stuff as possible out of the server
   10 proper and into loadable modules.  This makes the code much easier to read and
   11 understand.
   12   
   13   Expect this document to become more complete over time, as both the API and
   14 the person documenting it have a chance to mature a bit.  :)
   15   
   16   
   17    
   18   USER RELATED FUNCTIONS
   19   ----------------------
   20  
   21  The fundamental user data is stored in "struct ctdluser" which is defined
   22 in citadel.h.  The following functions are available:
   23   
   24  
   25  int getuser(struct ctdluser *usbuf, char name[])
   26  
   27  Given the name of a requested user and a buffer to store the user
   28 record in, getuser() will search the userlog for the named user and load its
   29 data into the buffer.  getuser() returns 0 upon success or a nonzero error
   30 code if the requested operation could not be performed.
   31  
   32  
   33  void putuser(struct ctdluser *usbuf, char *name)
   34  
   35  After reading in a user record with getuser() and perhaps modifying the data
   36 in some way, a program may use putuser() to write it back to disk.
   37  
   38  
   39  int lgetuser(struct ctdluser *usbuf, char *name)
   40  void lputuser(struct ctdluser *usbuf, char *name)
   41  
   42  If critical-section operation is required, this pair of calls may be used.
   43 They function the same as getuser() and putuser(), except that lgetuser()
   44 locks the user file immediately after retrieving the record and lputuser()
   45 unlocks it.  This will guarantee that no other threads manipulate the same
   46 user record at the same time.
   47  
   48  NOTE: do NOT attempt to combine the locking lgetuser/lputuser calls with any
   49 other locking calls in this API.  Attempting to obtain concurrent locks on
   50 multiple files may result in a deadlock condition which would freeze the
   51 entire server.
   52  
   53    
   54  void ForEachUser(void (*CallBack)(struct ctdluser *EachUser))
   55  
   56  This allows a user-supplied function to be called once for each user on
   57 the system.  The user-supplied function will be called with a pointer to a
   58 user structure as its only argument.
   59   
   60  
   61  int getuserbynumber(struct ctdluser *usbuf, long int number)
   62  
   63  getuserbynumber() functions similarly to getuser(), except that it is
   64 supplied with a user number rather than a name.  Calling this function
   65 results in a sequential search of the user file, so use it sparingly if at
   66 all.
   67  
   68  
   69  int purge_user(char *pname)
   70  
   71  This function deletes the named user off the system and erases all related
   72 objects: bio, photo, etc.  It returns 0 upon success or a nonzero error code
   73 if the requested operation could not be performed.
   74  
   75 
   76 
   77  HOW TO REGISTER FUNCTION HOOKS
   78  ------------------------------
   79  
   80  The truly powerful part of the Citadel API is the ability for extensions to
   81 register "hooks" -- user-supplied functions will be called while the server
   82 is performing various tasks.  Here are the API calls to register hooks:
   83  
   84    
   85  void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
   86  void CtdlUnregisterProtoHook(void (*handler)(char *), char *cmd)
   87   
   88  CtdlRegisterProtoHook() adds a new server command to the system.  The
   89 handler function should accept a single string parameter, which will be set
   90 to a string containing any parameters the client software sent along with
   91 the server command.  "cmd" should be the four-character mnemonic the server
   92 command is known by, and "desc" is a description of the new command.
   93 
   94  CtdlUnregisterProtoHook() removes a server command from the system.  It
   95 must be called with the same handler and cmd which were previously registered.
   96  
   97 
   98  void CtdlRegisterCleanupHook(void *fcn_ptr) 
   99  void CtdlUnregisterCleanupHook(void *fcn_ptr) 
  100  
  101  CtdlRegisterCleanupHook() registers a new function to be called whenever the
  102 server is shutting down.  Cleanup functions accept no parameters.
  103 
  104  CtdlUnregsiterCleanupHook() removes a cleanup function from the system.  It
  105 must be called with the same fcn_ptr which was previously registered.
  106 
  107  
  108 void CtdlRegisterSessionHook(void *fcn_ptr, int EventType) 
  109 void CtdlUnregisterSessionHook(void *fcn_ptr, int EventType) 
  110   
  111  CtdlRegisterSessionHook() registers a session hook.  Session hooks accept
  112 no parameters.  There are multiple types of session hooks; the server
  113 extension registers which one it is interested in by setting the value of
  114 EventType.  The available session hook types are:
  115 
  116 #define EVT_STOP	0	/* Session is terminating */
  117 #define EVT_START	1	/* Session is starting */
  118 #define EVT_LOGIN	2	/* A user is logging in */
  119 #define EVT_NEWROOM	3	/* Changing rooms */
  120 #define EVT_LOGOUT	4	/* A user is logging out */
  121 #define EVT_SETPASS	5	/* Setting or changing password */
  122 #define EVT_CMD		6	/* Called after each server command */
  123 #define EVT_RWHO	7	/* An RWHO command is being executed */
  124 #define EVT_ASYNC	8	/* Doing asynchronous message */
  125 
  126 #define EVT_TIMER	50	/* Timer events are called once per minute */
  127 #define EVT_HOUSE	51	/* Housekeeping event */
  128 
  129  CtdlUnregisterSessionHook() removes a session hook.  It must be called with
  130 the same fcn_ptr and EventTYpe which were previously registered.
  131  
  132 
  133 void CtdlRegisterUserHook(void *fcn_ptr, int EventType) 
  134 void CtdlUnregisterUserHook(void *fcn_ptr, int EventType) 
  135  
  136  CtdlRegisterUserHook() registers a user hook.  User hooks accept two
  137 parameters: a string pointer containing the user name, and a long which *may*
  138 contain a user number (only applicable for certain types of hooks).  The
  139 available user hook types are:
  140 
  141 #define EVT_PURGEUSER	100	/* Deleting a user */
  142 #define EVT_OUTPUTMSG	101	/* Outputting a message */
  143 
  144  CtdlUnregisterUserHook() removes a user hook from the system.  It must be
  145 called with the same fcn_ptr and EventType which were previously registered.
  146 
  147 
  148  void CtdlRegisterLogHook(void (*fcn_ptr) (char *), int loglevel)
  149  void CtdlUnregisterLogHook(void (*fcn_ptr) (char *), int loglevel)
  150 
  151  CtdlRegisterLogHook() adds a new logging function to the system.  The
  152 handler function should accept a single string as a parameter.  Logging
  153 functions can be used to implement additional logging facilities in
  154 addition to the Citadel trace file, which is output on stderr, or
  155 redirected to a file with the -t command line option.  The handler
  156 function will be called if the loglevel is greater than or equal to
  157 loglevel.
  158 
  159  Security considerations:  Logs may contain plain text passwords and
  160 other sensitive information.  It is your responsibility to ensure that
  161 your logs have appropriate access protection.  The Citadel trace file
  162 is readable only by the superuser when the -t option is used.
  163 
  164  CtdlUnregisterLogHook() removes a logging function from the system.  It
  165 must be called with the same fcn_ptr and loglevel which were previously
  166 registered.
  167 
  168 
  169  void CtdlRegisterMessageHook(int (*handler) (struct CtdlMessage *),
  170  				int EventType)
  171  void CtdlUnregisterMessageHook(int (*handler) (struct CtdlMessage *),
  172  				int EventType)
  173 
  174 
  175  CtdlRegisterMessageHook() registers a function with the message
  176 handling subsystem. This function will be called with one parameter, 
  177 a pointer to a CtdlMessage structure, when the message triggers an event 
  178 of type EventType. The registered function should return non zero if it 
  179 has handled the event to prevent other hook functions from also processing 
  180 the event.
  181 
  182  CtdlUnregisterMessageHook() removes a function from the list of registered 
  183 message handlers. To successfully remove a function registered with 
  184 CtdlRegisterMessageHook() CtdlUnregisterMessageHook() must be called with 
  185 the same parameters.
  186 
  187  Possible values for EventType are:
  188     EVT_BEFOREREAD   Called after a message is loaded from disk but before
  189 it is presented for reading.
  190     EVT_BEFORESAVE   Called before the message is saved to disk. returning 
  191 non zero for this event will prevent the message being saved to disk in the
  192 normal manner.
  193     EVT_AFTERSAVE    Called after the message is saved to disk but before
  194 any network spooling is carried out.
  195     EVT_SMTPSCAN     Called during the SMTP reception of a message after the 
  196 message is received and before the response is sent to the sender. This is
  197 intended for spam filters and virus checkers. A positive return code will
  198 cause the message to be rejected by the SMTP server.
  199 
  200 
  201  void CtdlRegisterRoomHook(int (*fcn_ptr) (char *))
  202  void CtdlUnregisterRoomHook(int (*fcn_ptr) (char *))
  203 
  204  Register or remove a function with the room processing system.
  205 Registered functions are called in the order they are registered when a message
  206 is added to a room. This allows modules to process new messages appearing in a room.
  207 
  208 
  209  void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
  210  void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
  211 
  212  Please write documentation for me!
  213 
  214 
  215  void CtdlRegisterServiceHook(int tcp_port, char *sockpath,
  216  				void (*h_greeting_function) (void),
  217 				void (*h_command_function) (void))
  218  void CtdlUnregisterServiceHook(int tcp_port, char *sockpath,
  219  				void (*h_greeting_function) (void),
  220 				void (*h_command_function) (void))
  221 
  222  Please write documentation for me!
  223 
  224 
  225   FUNCTIONS WHICH MANIPULATE USER/ROOM RELATIONSHIPS
  226 
  227  void CtdlGetRelationship(struct visit *vbuf,
  228                         struct ctdluser *rel_user,
  229                         struct ctdlroom *rel_room);
  230  void CtdlSetRelationship(struct visit *newvisit,
  231                         struct ctdluser *rel_user,
  232                         struct ctdlroom *rel_room);
  233  
  234  These functions get/set a "struct visit" structure which may contain
  235 information about the relationship between a user and a room.  Specifically:
  236 
  237 struct visit {
  238         char v_roomname[20];
  239         long v_generation;
  240         long v_lastseen;
  241         unsigned int v_flags;
  242         };
  243 
  244 #define V_FORGET        1               /* User has zapped this room        */
  245 #define V_LOCKOUT       2               /* User is locked out of this room  */
  246 #define V_ACCESS        4               /* Access is granted to this room   */
  247  
  248  Don't change v_roomname or v_generation; they're used to identify the room
  249 being referred to.  A room is unique to the system by its combination of room
  250 name and generation number.  If a new room is created with the same name as
  251 a recently deleted room, it will have a new generation number, and therefore
  252 stale "visit" records will not be applied (and will eventually be purged).
  253  
  254  v_lastseen contains the number of the newest message the user has read in
  255 this room.  Any existing messages higher than this number can be considered
  256 as "new messages."
  257  
  258  v_flags contains information regarding access to the room.
  259  
  260   
  261  
  262  int CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf)
  263  
  264  This is a convenience function which uses CtdlGetRelationship() to determine
  265 whether a user has access to a room.  It returns a bucket of bits which may
  266 contain:
  267  
  268 #define UA_INUSE                1	/* Room exists */
  269 #define UA_KNOWN                2	/* Room is in user's Known list */
  270 #define UA_GOTOALLOWED          4	/* User may <.G>oto this room */
  271 #define UA_HASNEWMSGS           8	/* Room contains new messages */
  272 #define UA_ZAPPED		16	/* User has forgotten this room */
  273 
  274 
  275 
  276 
  277    ROOM RELATED FUNCTIONS
  278    ----------------------
  279  
  280  
  281 unsigned create_room(char *new_room_name,
  282                      int new_room_type,
  283                      char *new_room_pass,
  284                      int new_room_floor,
  285 		     int really_create)
  286  
  287  This function is used to create a new room.  new_room_name should be set to
  288 the desired name for the new room.
  289   
  290  new_room_type should be set to one of the following values:
  291 	0 = public room
  292 	1 = guess-name room
  293 	2 = passworded room
  294 	3 = invitation-only room
  295 	4 = personal (mailbox) room
  296 	5 = personal (mailbox) room, and new_room_name already contains
  297 	    the namespace prefix (use with caution!)
  298  
  299  new_room_pass should be set to the desired password for the room (obviously
  300 this is only valid for passworded rooms).
  301  
  302  If the room is really to be created, set really_create to 1.  Otherwise, the
  303 caller may merely check to see if it's possible to create the room without
  304 actually creating it by setting really_create to 0.
  305   
  306  create_room() returns the flags associated with the new room (as in the
  307 data structure item room.QRflags).  If the room cannot be created (for
  308 example, a room with the name already exists), it returns 0.
  309  
  310