File: citadelapi.txt

package info (click to toggle)
citadel 902-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,904 kB
  • ctags: 4,359
  • sloc: ansic: 54,083; sh: 4,226; yacc: 651; makefile: 413; xml: 40
file content (311 lines) | stat: -rw-r--r-- 12,568 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
 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 ctdluser" which is defined
in citadel.h.  The following functions are available:
  
 
 int getuser(struct ctdluser *usbuf, char name[])
 
 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 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 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()
locks the user file immediately after retrieving the record and lputuser()
unlocks it.  This will guarantee that no other threads manipulate the same
user record at the same time.
 
 NOTE: do NOT attempt to combine the locking lgetuser/lputuser calls with any
other locking calls in this API.  Attempting to obtain concurrent locks on
multiple files may result in a deadlock condition which would freeze the
entire server.
 
   
 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
user structure as its only argument.
  
 
 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
results in a sequential search of the user file, so use it sparingly if at
all.
 
 
 int purge_user(char *pname)
 
 This function deletes the named user off the system and erases all related
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 */
#define EVT_CMD		6	/* Called after each server command */
#define EVT_RWHO	7	/* An RWHO command is being executed */
#define EVT_ASYNC	8	/* Doing asynchronous message */

#define EVT_TIMER	50	/* Timer events are called once per minute */
#define EVT_HOUSE	51	/* Housekeeping event */

 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)


 CtdlRegisterMessageHook() registers a function with the message
handling subsystem. This function will be called with one parameter, 
a pointer to a CtdlMessage structure, when the message triggers an event 
of type EventType. The registered function should return non zero if it 
has handled the event to prevent other hook functions from also processing 
the event.

 CtdlUnregisterMessageHook() removes a function from the list of registered 
message handlers. To successfully remove a function registered with 
CtdlRegisterMessageHook() CtdlUnregisterMessageHook() must be called with 
the same parameters.

 Possible values for EventType are:
    EVT_BEFOREREAD   Called after a message is loaded from disk but before
it is presented for reading.
    EVT_BEFORESAVE   Called before the message is saved to disk. returning 
non zero for this event will prevent the message being saved to disk in the
normal manner.
    EVT_AFTERSAVE    Called after the message is saved to disk but before
any IGnet spooling is carried out.
    EVT_SMTPSCAN     Called during the SMTP reception of a message after the 
message is received and before the response is sent to the sender. This is
intended for spam filters and virus checkers. A positive return code will
cause the message to be rejected by the SMTP server.


 void CtdlRegisterRoomHook(int (*fcn_ptr) (char *))
 void CtdlUnregisterRoomHook(int (*fcn_ptr) (char *))

 Register or remove a function with the room processing system.
Registered functions are called in the order they are registered when a message
is added to a room. This allows modules such as Sieve to process new messages
appearing in a room.


 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.