]> code.citadel.org Git - citadel.git/blobdiff - citadel/techdoc/citadelapi.txt
* Replaced all "Citadel/UX" references with "Citadel"
[citadel.git] / citadel / techdoc / citadelapi.txt
index a092f5365ff6111610dbf2e546fa07d148134fec..00dfa1b46398940e977bd8135669fab65d12bdc0 100644 (file)
@@ -1,31 +1,43 @@
-Here's "take two" on the CitadelAPI extension library.  These days it's not
-really a library at all, but rather a list of stuff that's inside the server that
-might be useful.  Sort of.  We'll see how it evolves.
-
+ Citadel Server Extension API Documentation
+ ---------------------------------------------
+  This is a VERY INCOMPLETE documentation of the API for extending the
+Citadel server using dynamically loaded modules.  It really isn't an API at
+all, but rather a list of some of the functions available in the server which
+are likely to be of use to module writers.
  
+  The current trend is to move as much stuff as possible out of the server
+proper and into loadable modules.  This makes the code much easier to read and
+understand.
+  
+  Expect this document to become more complete over time, as both the API and
+the person documenting it have a chance to mature a bit.  :)
+  
+  
+   
   USER RELATED FUNCTIONS
   ----------------------
  
- The fundamental user data is stored in "struct usersupp" which is defined
+ The fundamental user data is stored in "struct ctdluser" which is defined
 in citadel.h.  The following functions are available:
   
  
- int getuser(struct usersupp *usbuf, char name[])
+ int getuser(struct ctdluser *usbuf, char name[])
  
- Given the name of a requested user and a buffer to store the usersupp
+ Given the name of a requested user and a buffer to store the user
 record in, getuser() will search the userlog for the named user and load its
 data into the buffer.  getuser() returns 0 upon success or a nonzero error
 code if the requested operation could not be performed.
  
  
- void putuser(struct usersupp *usbuf, char *name)
+ void putuser(struct ctdluser *usbuf, char *name)
  
  After reading in a user record with getuser() and perhaps modifying the data
 in some way, a program may use putuser() to write it back to disk.
  
  
- int lgetuser(struct usersupp *usbuf, char *name)
- void lputuser(struct usersupp *usbuf, char *name)
+ int lgetuser(struct ctdluser *usbuf, char *name)
+ void lputuser(struct ctdluser *usbuf, char *name)
  
  If critical-section operation is required, this pair of calls may be used.
 They function the same as getuser() and putuser(), except that lgetuser()
@@ -39,14 +51,14 @@ multiple files may result in a deadlock condition which would freeze the
 entire server.
  
    
- void ForEachUser(void (*CallBack)(struct usersupp *EachUser))
+ void ForEachUser(void (*CallBack)(struct ctdluser *EachUser))
  
  This allows a user-supplied function to be called once for each user on
 the system.  The user-supplied function will be called with a pointer to a
-usersupp structure as its only argument.
+user structure as its only argument.
   
  
- int getuserbynumber(struct usersupp *usbuf, long int number)
+ int getuserbynumber(struct ctdluser *usbuf, long int number)
  
  getuserbynumber() functions similarly to getuser(), except that it is
 supplied with a user number rather than a name.  Calling this function
@@ -60,4 +72,201 @@ all.
 objects: bio, photo, etc.  It returns 0 upon success or a nonzero error code
 if the requested operation could not be performed.
  
+
+
+ HOW TO REGISTER FUNCTION HOOKS
+ ------------------------------
+ The truly powerful part of the Citadel API is the ability for extensions to
+register "hooks" -- user-supplied functions will be called while the server
+is performing various tasks.  Here are the API calls to register hooks:
+   
+ void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
+ void CtdlUnregisterProtoHook(void (*handler)(char *), char *cmd)
+  
+ CtdlRegisterProtoHook() adds a new server command to the system.  The
+handler function should accept a single string parameter, which will be set
+to a string containing any parameters the client software sent along with
+the server command.  "cmd" should be the four-character mnemonic the server
+command is known by, and "desc" is a description of the new command.
+
+ CtdlUnregisterProtoHook() removes a server command from the system.  It
+must be called with the same handler and cmd which were previously registered.
+
+ void CtdlRegisterCleanupHook(void *fcn_ptr) 
+ void CtdlUnregisterCleanupHook(void *fcn_ptr) 
+ CtdlRegisterCleanupHook() registers a new function to be called whenever the
+server is shutting down.  Cleanup functions accept no parameters.
+
+ CtdlUnregsiterCleanupHook() removes a cleanup function from the system.  It
+must be called with the same fcn_ptr which was previously registered.
+
+void CtdlRegisterSessionHook(void *fcn_ptr, int EventType) 
+void CtdlUnregisterSessionHook(void *fcn_ptr, int EventType) 
+  
+ CtdlRegisterSessionHook() registers a session hook.  Session hooks accept
+no parameters.  There are multiple types of session hooks; the server
+extension registers which one it is interested in by setting the value of
+EventType.  The available session hook types are:
+
+#define EVT_STOP       0       /* Session is terminating */
+#define EVT_START      1       /* Session is starting */
+#define EVT_LOGIN      2       /* A user is logging in */
+#define EVT_NEWROOM    3       /* Changing rooms */
+#define EVT_LOGOUT     4       /* A user is logging out */
+#define EVT_SETPASS    5       /* Setting or changing password */
+
+ CtdlUnregisterSessionHook() removes a session hook.  It must be called with
+the same fcn_ptr and EventTYpe which were previously registered.
+
+void CtdlRegisterUserHook(void *fcn_ptr, int EventType) 
+void CtdlUnregisterUserHook(void *fcn_ptr, int EventType) 
+ CtdlRegisterUserHook() registers a user hook.  User hooks accept two
+parameters: a string pointer containing the user name, and a long which *may*
+contain a user number (only applicable for certain types of hooks).  The
+available user hook types are:
+
+#define EVT_PURGEUSER  100     /* Deleting a user */
+#define EVT_OUTPUTMSG  101     /* Outputting a message */
+
+ CtdlUnregisterUserHook() removes a user hook from the system.  It must be
+called with the same fcn_ptr and EventType which were previously registered.
+
+
+ void CtdlRegisterLogHook(void (*fcn_ptr) (char *), int loglevel)
+ void CtdlUnregisterLogHook(void (*fcn_ptr) (char *), int loglevel)
+
+ CtdlRegisterLogHook() adds a new logging function to the system.  The
+handler function should accept a single string as a parameter.  Logging
+functions can be used to implement additional logging facilities in
+addition to the Citadel trace file, which is output on stderr, or
+redirected to a file with the -t command line option.  The handler
+function will be called if the loglevel is greater than or equal to
+loglevel.
+
+ Security considerations:  Logs may contain plain text passwords and
+other sensitive information.  It is your responsibility to ensure that
+your logs have appropriate access protection.  The Citadel trace file
+is readable only by the superuser when the -t option is used.
+
+ CtdlUnregisterLogHook() removes a logging function from the system.  It
+must be called with the same fcn_ptr and loglevel which were previously
+registered.
+
+
+ void CtdlRegisterMessageHook(int (*handler) (struct CtdlMessage *),
+                               int EventType)
+ void CtdlUnregisterMessageHook(int (*handler) (struct CtdlMessage *),
+                               int EventType)
+
+ Please write documentation for me!
+
+
+ void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
+ void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
+
+ Please write documentation for me!
+
+
+ void CtdlRegisterServiceHook(int tcp_port, char *sockpath,
+                               void (*h_greeting_function) (void),
+                               void (*h_command_function) (void))
+ void CtdlUnregisterServiceHook(int tcp_port, char *sockpath,
+                               void (*h_greeting_function) (void),
+                               void (*h_command_function) (void))
+
+ Please write documentation for me!
+
+
+  FUNCTIONS WHICH MANIPULATE USER/ROOM RELATIONSHIPS
+
+ void CtdlGetRelationship(struct visit *vbuf,
+                        struct ctdluser *rel_user,
+                        struct ctdlroom *rel_room);
+ void CtdlSetRelationship(struct visit *newvisit,
+                        struct ctdluser *rel_user,
+                        struct ctdlroom *rel_room);
+ These functions get/set a "struct visit" structure which may contain
+information about the relationship between a user and a room.  Specifically:
+
+struct visit {
+        char v_roomname[20];
+        long v_generation;
+        long v_lastseen;
+        unsigned int v_flags;
+        };
+
+#define V_FORGET        1               /* User has zapped this room        */
+#define V_LOCKOUT       2               /* User is locked out of this room  */
+#define V_ACCESS        4               /* Access is granted to this room   */
+ Don't change v_roomname or v_generation; they're used to identify the room
+being referred to.  A room is unique to the system by its combination of room
+name and generation number.  If a new room is created with the same name as
+a recently deleted room, it will have a new generation number, and therefore
+stale "visit" records will not be applied (and will eventually be purged).
+ v_lastseen contains the number of the newest message the user has read in
+this room.  Any existing messages higher than this number can be considered
+as "new messages."
+ v_flags contains information regarding access to the room.
+  
+ int CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf)
+ This is a convenience function which uses CtdlGetRelationship() to determine
+whether a user has access to a room.  It returns a bucket of bits which may
+contain:
+#define UA_INUSE                1      /* Room exists */
+#define UA_KNOWN                2      /* Room is in user's Known list */
+#define UA_GOTOALLOWED          4      /* User may <.G>oto this room */
+#define UA_HASNEWMSGS           8      /* Room contains new messages */
+#define UA_ZAPPED              16      /* User has forgotten this room */
+
+
+
+
+   ROOM RELATED FUNCTIONS
+   ----------------------
+unsigned create_room(char *new_room_name,
+                     int new_room_type,
+                     char *new_room_pass,
+                     int new_room_floor,
+                    int really_create)
+ This function is used to create a new room.  new_room_name should be set to
+the desired name for the new room.
+  
+ new_room_type should be set to one of the following values:
+       0 = public room
+       1 = guess-name room
+       2 = passworded room
+       3 = invitation-only room
+       4 = personal (mailbox) room
+       5 = personal (mailbox) room, and new_room_name already contains
+           the namespace prefix (use with caution!)
+ new_room_pass should be set to the desired password for the room (obviously
+this is only valid for passworded rooms).
+ If the room is really to be created, set really_create to 1.  Otherwise, the
+caller may merely check to see if it's possible to create the room without
+actually creating it by setting really_create to 0.
+  
+ create_room() returns the flags associated with the new room (as in the
+data structure item room.QRflags).  If the room cannot be created (for
+example, a room with the name already exists), it returns 0.