1 Citadel/UX Server Extension API Documentation
2 ---------------------------------------------
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.
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
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. :)
18 USER RELATED FUNCTIONS
19 ----------------------
21 The fundamental user data is stored in "struct usersupp" which is defined
22 in citadel.h. The following functions are available:
25 int getuser(struct usersupp *usbuf, char name[])
27 Given the name of a requested user and a buffer to store the usersupp
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.
33 void putuser(struct usersupp *usbuf, char *name)
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.
39 int lgetuser(struct usersupp *usbuf, char *name)
40 void lputuser(struct usersupp *usbuf, char *name)
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.
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
54 void ForEachUser(void (*CallBack)(struct usersupp *EachUser))
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 usersupp structure as its only argument.
61 int getuserbynumber(struct usersupp *usbuf, long int number)
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
69 int purge_user(char *pname)
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.
77 HOW TO REGISTER FUNCTION HOOKS
78 ------------------------------
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:
85 void CtdlRegisterProtoHook(void (*handler)(char *), char *cmd, char *desc)
86 void CtdlUnregisterProtoHook(void (*handler)(char *), char *cmd)
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.
94 CtdlUnregisterProtoHook() removes a server command from the system. It
95 must be called with the same handler and cmd which were previously registered.
98 void CtdlRegisterCleanupHook(void *fcn_ptr)
99 void CtdlUnregisterCleanupHook(void *fcn_ptr)
101 CtdlRegisterCleanupHook() registers a new function to be called whenever the
102 server is shutting down. Cleanup functions accept no parameters.
104 CtdlUnregsiterCleanupHook() removes a cleanup function from the system. It
105 must be called with the same fcn_ptr which was previously registered.
108 void CtdlRegisterSessionHook(void *fcn_ptr, int EventType)
109 void CtdlUnregisterSessionHook(void *fcn_ptr, int EventType)
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:
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 */
123 CtdlUnregisterSessionHook() removes a session hook. It must be called with
124 the same fcn_ptr and EventTYpe which were previously registered.
127 void CtdlRegisterUserHook(void *fcn_ptr, int EventType)
128 void CtdlUnregisterUserHook(void *fcn_ptr, int EventType)
130 CtdlRegisterUserHook() registers a user hook. User hooks accept two
131 parameters: a string pointer containing the user name, and a long which *may*
132 contain a user number (only applicable for certain types of hooks). The
133 available user hook types are:
135 #define EVT_PURGEUSER 100 /* Deleting a user */
136 #define EVT_OUTPUTMSG 101 /* Outputting a message */
138 CtdlUnregisterUserHook() removes a user hook from the system. It must be
139 called with the same fcn_ptr and EventType which were previously registered.
142 void CtdlRegisterLogHook(void (*fcn_ptr) (char *), int loglevel)
143 void CtdlUnregisterLogHook(void (*fcn_ptr) (char *), int loglevel)
145 CtdlRegisterLogHook() adds a new logging function to the system. The
146 handler function should accept a single string as a parameter. Logging
147 functions can be used to implement additional logging facilities in
148 addition to the Citadel trace file, which is output on stderr, or
149 redirected to a file with the -t command line option. The handler
150 function will be called if the loglevel is greater than or equal to
153 Security considerations: Logs may contain plain text passwords and
154 other sensitive information. It is your responsibility to ensure that
155 your logs have appropriate access protection. The Citadel trace file
156 is readable only by the superuser when the -t option is used.
158 CtdlUnregisterLogHook() removes a logging function from the system. It
159 must be called with the same fcn_ptr and loglevel which were previously
163 void CtdlRegisterMessageHook(int (*handler) (struct CtdlMessage *),
165 void CtdlUnregisterMessageHook(int (*handler) (struct CtdlMessage *),
168 Please write documentation for me!
171 void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
172 void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
174 Please write documentation for me!
177 void CtdlRegisterServiceHook(int tcp_port, char *sockpath,
178 void (*h_greeting_function) (void),
179 void (*h_command_function) (void))
180 void CtdlUnregisterServiceHook(int tcp_port, char *sockpath,
181 void (*h_greeting_function) (void),
182 void (*h_command_function) (void))
184 Please write documentation for me!
187 FUNCTIONS WHICH MANIPULATE USER/ROOM RELATIONSHIPS
189 void CtdlGetRelationship(struct visit *vbuf,
190 struct usersupp *rel_user,
191 struct quickroom *rel_room);
192 void CtdlSetRelationship(struct visit *newvisit,
193 struct usersupp *rel_user,
194 struct quickroom *rel_room);
196 These functions get/set a "struct visit" structure which may contain
197 information about the relationship between a user and a room. Specifically:
203 unsigned int v_flags;
206 #define V_FORGET 1 /* User has zapped this room */
207 #define V_LOCKOUT 2 /* User is locked out of this room */
208 #define V_ACCESS 4 /* Access is granted to this room */
210 Don't change v_roomname or v_generation; they're used to identify the room
211 being referred to. A room is unique to the system by its combination of room
212 name and generation number. If a new room is created with the same name as
213 a recently deleted room, it will have a new generation number, and therefore
214 stale "visit" records will not be applied (and will eventually be purged).
216 v_lastseen contains the number of the newest message the user has read in
217 this room. Any existing messages higher than this number can be considered
220 v_flags contains information regarding access to the room.
224 int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf)
226 This is a convenience function which uses CtdlGetRelationship() to determine
227 whether a user has access to a room. It returns a bucket of bits which may
230 #define UA_INUSE 1 /* Room exists */
231 #define UA_KNOWN 2 /* Room is in user's Known list */
232 #define UA_GOTOALLOWED 4 /* User may <.G>oto this room */
233 #define UA_HASNEWMSGS 8 /* Room contains new messages */
234 #define UA_ZAPPED 16 /* User has forgotten this room */
239 ROOM RELATED FUNCTIONS
240 ----------------------
243 unsigned create_room(char *new_room_name,
249 This function is used to create a new room. new_room_name should be set to
250 the desired name for the new room.
252 new_room_type should be set to one of the following values:
256 3 = invitation-only room
257 4 = personal (mailbox) room
258 5 = personal (mailbox) room, and new_room_name already contains
259 the namespace prefix (use with caution!)
261 new_room_pass should be set to the desired password for the room (obviously
262 this is only valid for passworded rooms).
264 If the room is really to be created, set really_create to 1. Otherwise, the
265 caller may merely check to see if it's possible to create the room without
266 actually creating it by setting really_create to 0.
268 create_room() returns the flags associated with the new room (as in the
269 data structure item quickroom.QRflags). If the room cannot be created (for
270 example, a room with the name already exists), it returns 0.