* Updated some of the docs. Bumped version number to 5.80 in anticipation
[citadel.git] / citadel / techdoc / citadelapi.txt
1  Citadel/UX 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 usersupp" which is defined
22 in citadel.h.  The following functions are available:
23   
24  
25  int getuser(struct usersupp *usbuf, char name[])
26  
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.
31  
32  
33  void putuser(struct usersupp *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 usersupp *usbuf, char *name)
40  void lputuser(struct usersupp *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 usersupp *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 usersupp structure as its only argument.
59   
60  
61  int getuserbynumber(struct usersupp *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   
87  Adds a new server command to the system.  The handler function should accept
88 a single string parameter, which will be set to a string containing any
89 parameters the client software sent along with the server command.  "cmd" 
90 should be the four-character mnemonic the server command is known by, and
91 "desc" is a description of the new command.
92  
93
94  void CtdlRegisterCleanupHook(void *fcn_ptr) 
95  
96  Registers a new function to be called whenever the server is shutting down.
97 Cleanup functions accept no parameters.
98
99  
100 void CtdlRegisterSessionHook(void *fcn_ptr, int EventType) 
101   
102  Registers a session hook.  Session hooks accept no parameters.  There are
103 multiple types of session hooks; the server extension registers which one it
104 is interested in by setting the value of EventType.  The available session
105 hook types are:
106
107 #define EVT_STOP        0       /* Session is terminating */
108 #define EVT_START       1       /* Session is starting */
109 #define EVT_LOGIN       2       /* A user is logging in */
110 #define EVT_NEWROOM     3       /* Changing rooms */
111 #define EVT_LOGOUT      4       /* A user is logging out */
112 #define EVT_SETPASS     5       /* Setting or changing password */
113
114  
115 void CtdlRegisterUserHook(void *fcn_ptr, int EventType) 
116  
117  Registers a user hook.  User hooks accept two parameters: a string pointer
118 containing the user name, and a long which *may* contain a user number (only
119 applicable for certain types of hooks).  The available user hook types are:
120
121 #define EVT_PURGEUSER   100     /* Deleting a user */
122 #define EVT_OUTPUTMSG   101     /* Outputting a message */
123
124
125    
126   FUNCTIONS WHICH MANIPULATE USER/ROOM RELATIONSHIPS
127
128  void CtdlGetRelationship(struct visit *vbuf,
129                         struct usersupp *rel_user,
130                         struct quickroom *rel_room);
131  void CtdlSetRelationship(struct visit *newvisit,
132                         struct usersupp *rel_user,
133                         struct quickroom *rel_room);
134  
135  These functions get/set a "struct visit" structure which may contain
136 information about the relationship between a user and a room.  Specifically:
137
138 struct visit {
139         char v_roomname[20];
140         long v_generation;
141         long v_lastseen;
142         unsigned int v_flags;
143         };
144
145 #define V_FORGET        1               /* User has zapped this room        */
146 #define V_LOCKOUT       2               /* User is locked out of this room  */
147 #define V_ACCESS        4               /* Access is granted to this room   */
148  
149  Don't change v_roomname or v_generation; they're used to identify the room
150 being referred to.  A room is unique to the system by its combination of room
151 name and generation number.  If a new room is created with the same name as
152 a recently deleted room, it will have a new generation number, and therefore
153 stale "visit" records will not be applied (and will eventually be purged).
154  
155  v_lastseen contains the number of the newest message the user has read in
156 this room.  Any existing messages higher than this number can be considered
157 as "new messages."
158  
159  v_flags contains information regarding access to the room.
160  
161   
162  
163  int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf)
164  
165  This is a convenience function which uses CtdlGetRelationship() to determine
166 whether a user has access to a room.  It returns a bucket of bits which may
167 contain:
168  
169 #define UA_INUSE                1       /* Room exists */
170 #define UA_KNOWN                2       /* Room is in user's Known list */
171 #define UA_GOTOALLOWED          4       /* User may <.G>oto this room */
172 #define UA_HASNEWMSGS           8       /* Room contains new messages */
173 #define UA_ZAPPED               16      /* User has forgotten this room */
174
175
176
177
178    ROOM RELATED FUNCTIONS
179    ----------------------
180  
181  
182 unsigned create_room(char *new_room_name,
183                      int new_room_type,
184                      char *new_room_pass,
185                      int new_room_floor,
186                      int really_create)
187  
188  This function is used to create a new room.  new_room_name should be set to
189 the desired name for the new room.
190   
191  new_room_type should be set to one of the following values:
192         0 = public room
193         1 = guess-name room
194         2 = passworded room
195         3 = invitation-only room
196         4 = personal (mailbox) room
197         5 = personal (mailbox) room, and new_room_name already contains
198             the namespace prefix (use with caution!)
199  
200  new_room_pass should be set to the desired password for the room (obviously
201 this is only valid for passworded rooms).
202  
203  If the room is really to be created, set really_create to 1.  Otherwise, the
204 caller may merely check to see if it's possible to create the room without
205 actually creating it by setting really_create to 0.
206   
207  create_room() returns the flags associated with the new room (as in the
208 data structure item quickroom.QRflags).  If the room cannot be created (for
209 example, a room with the name already exists), it returns 0.
210  
211