Tue Aug 18 00:42:33 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
[citadel.git] / citadel / citadelapi.c
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <time.h>
5 #include <ctype.h>
6 #include <string.h>
7 #include <errno.h>
8 #include "citadel.h"
9 #include "serv_info.h"
10 #include "ipc.h"
11 #include "citadelapi.h"
12
13
14 struct CtdlInternalList {
15         struct CtdlInternalList *next;
16         char data[256];
17         };
18
19
20 struct CtdlServerHandle CtdlAppHandle;
21 struct CtdlServInfo CtdlAppServInfo;
22 int CtdlErrno = 0;
23
24 void logoff(int exitcode) {
25         exit(exitcode);
26         }
27
28
29
30 /*
31  * CtdlInternalNumParms()  -  discover number of parameters...
32  */
33 int CtdlInternalNumParms(char *source)
34 {
35         int a;
36         int count = 1;
37
38         for (a=0; a<strlen(source); ++a) 
39                 if (source[a]=='|') ++count;
40         return(count);
41         }
42
43 /*
44  * CtdlInternalExtract()  -  extract a parameter from a series of "|" separated
45  */
46 void CtdlInternalExtract(char *dest, char *source, int parmnum)
47 {
48         char buf[256];
49         int count = 0;
50         int n;
51
52         if (strlen(source)==0) {
53                 strcpy(dest,"");
54                 return;
55                 }
56
57         n = CtdlInternalNumParms(source);
58
59         if (parmnum >= n) {
60                 strcpy(dest,"");
61                 return;
62                 }
63         strcpy(buf,source);
64         if ( (parmnum == 0) && (n == 1) ) {
65                 strcpy(dest,buf);
66                 for (n=0; n<strlen(dest); ++n)
67                         if (dest[n]=='|') dest[n] = 0;
68                 return;
69                 }
70
71         while (count++ < parmnum) do {
72                 strcpy(buf,&buf[1]);
73                 } while( (strlen(buf)>0) && (buf[0]!='|') );
74         if (buf[0]=='|') strcpy(buf,&buf[1]);
75         for (count = 0; count<strlen(buf); ++count)
76                 if (buf[count] == '|') buf[count] = 0;
77         strcpy(dest,buf);
78         }
79
80 /*
81  * CtdlInternalExtractInt()  -  CtdlInternalExtract an int parm w/o supplying a buffer
82  */
83 int CtdlInternalExtractInt(char *source, int parmnum)
84 {
85         char buf[256];
86         
87         CtdlInternalExtract(buf,source,parmnum);
88         return(atoi(buf));
89         }
90
91 /*
92  * CtdlInternalExtractLong()  -  CtdlInternalExtract an long parm w/o supplying a buffer
93  */
94 long CtdlInternalExtractLong(char *source, long int parmnum)
95 {
96         char buf[256];
97         
98         CtdlInternalExtract(buf,source,parmnum);
99         return(atol(buf));
100         }
101
102
103
104
105
106
107
108
109
110
111
112
113 /*
114  * Programs linked against the Citadel server extension library need to
115  * be called with the following arguments:
116  * 0 - program name (as always)
117  * 1 - server address (usually 127.0.0.1)
118  * 2 - server port number
119  * 3 - internal program secret
120  * 4 - user name
121  * 5 - user password
122  * 6 - initial room
123  * 7 - associated client session
124  * 
125  */
126
127 int
128 main(int argc, char *argv[])
129 {
130         int a;
131         char buf[256];
132
133         /* We're really not interested in stdio */
134         close(0);
135         close(1);
136         close(2);
137
138         /* Bail out if someone tries to run this thing manually */
139         if (argc < 3) exit(1);
140
141         /* Zeroing out the server handle neatly sets the values of
142          * CtdlAppHandle to sane default values
143          */
144         bzero(&CtdlAppHandle, sizeof(struct CtdlServerHandle));
145
146         /* Now parse the command-line arguments fed to us by the server */
147         for (a=0; a<argc; ++a) switch(a) {
148                 case 1: strcpy(CtdlAppHandle.ServerAddress, argv[a]);
149                         break;
150                 case 2: CtdlAppHandle.ServerPort = atoi(argv[a]);
151                         break;
152                 case 3: strcpy(CtdlAppHandle.ipgmSecret, argv[a]);
153                         break;
154                 case 4: strcpy(CtdlAppHandle.UserName, argv[a]);
155                         break;
156                 case 5: strcpy(CtdlAppHandle.Password, argv[a]);
157                         break;
158                 case 6: strcpy(CtdlAppHandle.InitialRoom, argv[a]);
159                         break;
160                 case 7: CtdlAppHandle.AssocClientSession = atoi(argv[a]);
161                         break;
162                 }
163
164         /* Connect to the server */
165         argc = 3;
166         attach_to_server(argc, argv);
167         serv_gets(buf);
168         if (buf[0] != '2') exit(1);
169
170         /* Set up the server environment to our liking */
171
172         CtdlInternalGetServInfo(&CtdlAppServInfo);
173
174         sprintf(buf, "IDEN 0|5|006|CitadelAPI Client");
175         serv_puts(buf);
176         serv_gets(buf);
177
178         if (strlen(CtdlAppHandle.ipgmSecret) > 0) {
179                 sprintf(buf, "IPGM %s", CtdlAppHandle.ipgmSecret);
180                 serv_puts(buf);
181                 serv_gets(buf);
182                 }
183
184         if (strlen(CtdlAppHandle.UserName) > 0) {
185                 sprintf(buf, "USER %s", CtdlAppHandle.UserName);
186                 serv_puts(buf);
187                 serv_gets(buf);
188                 sprintf(buf, "PASS %s", CtdlAppHandle.Password);
189                 serv_puts(buf);
190                 serv_gets(buf);
191                 }
192
193         sprintf(buf, "GOTO %s", CtdlAppHandle.InitialRoom);
194         serv_puts(buf);
195         serv_gets(buf);
196         if (buf[0] != '2') {
197                 serv_puts("GOTO _BASEROOM_");
198                 serv_gets(buf);
199                 }
200
201         /* Now do the loop. */
202         CtdlMain();
203
204         /* Clean up gracefully and exit. */
205         serv_puts("QUIT");
206         exit(0);
207         }
208
209
210 int CtdlGetLastError(void) {
211         return CtdlErrno;
212         }
213
214
215 int CtdlSendExpressMessage(char *ToUser, char *MsgText) {
216         char buf[256];
217
218         if (strlen(ToUser) + strlen(MsgText) > 248) {
219                 CtdlErrno = ERROR + TOO_BIG;
220                 return CtdlErrno;
221                 }
222
223         sprintf(buf, "SEXP %s|%s", ToUser, MsgText);
224         serv_puts(buf);
225         serv_gets(buf);
226         
227         CtdlErrno = atoi(buf);
228         if (CtdlErrno == OK) CtdlErrno = 0;
229         return CtdlErrno;
230         }
231
232
233
234 int CtdlInternalGetUserParam(char *ParamBuf, int ParamNum, char *WhichUser) {
235         char buf[256];
236
237         sprintf(buf, "AGUP %s", WhichUser);
238         serv_puts(buf);
239         serv_gets(buf);
240         if (buf[0] != '2') return(atoi(buf));
241         CtdlInternalExtract(ParamBuf, &buf[4], ParamNum);
242         return(0);
243         }
244
245
246 int CtdlInternalSetUserParam(char *ParamBuf, int ParamNum, char *WhichUser) {
247         char buf[256];
248         char params[8][256];
249         int a;
250
251         sprintf(buf, "AGUP %s", WhichUser);
252         serv_puts(buf);
253         serv_gets(buf);
254         if (buf[0] != '2') return(atoi(buf));
255         for (a=0; a<8; ++a) {
256                 CtdlInternalExtract(&params[a][0], &buf[4], a);
257                 }
258         strcpy(&params[ParamNum][0], ParamBuf);
259         strcpy(buf, "ASUP ");
260         for (a=0; a<8; ++a) {
261                 strcat(buf, &params[a][0]);
262                 strcat(buf, "|");
263                 }
264         serv_puts(buf);
265         serv_gets(buf);
266         if (buf[0] != '2') return(atoi(buf));
267         return(0);
268         }
269
270 /*
271  0 - User name
272  1 - Password
273  2 - Flags (see citadel.h)
274  3 - Times called
275  4 - Messages posted
276  5 - Access level
277  6 - User number
278  7 - Timestamp of last call
279  */
280
281 int CtdlGetUserPassword(char *buf, char *WhichUser) {
282         CtdlErrno = CtdlInternalGetUserParam(buf, 1, WhichUser);
283         return(CtdlErrno);
284         }
285
286 int CtdlSetUserPassword(char *buf, char *WhichUser) {
287         CtdlErrno = CtdlInternalSetUserParam(buf, 1, WhichUser);
288         return(CtdlErrno);
289         }
290
291 unsigned int CtdlGetUserFlags(char *WhichUser) {
292         char buf[256];
293         CtdlErrno = CtdlInternalGetUserParam(buf, 2, WhichUser);
294         return((CtdlErrno == 0) ? atoi(buf) : (-1));
295         }
296
297 int CtdlSetUserFlags(unsigned int NewFlags, char *WhichUser) {
298         char buf[256];
299         sprintf(buf, "%u", NewFlags);
300         CtdlErrno = CtdlInternalGetUserParam(buf, 2, WhichUser);
301         return(CtdlErrno);
302         }
303
304 int CtdlGetUserTimesCalled(char *WhichUser) {
305         char buf[256];
306         CtdlErrno = CtdlInternalGetUserParam(buf, 3, WhichUser);
307         return((CtdlErrno == 0) ? atoi(buf) : (-1));
308         }
309
310 int CtdlSetUserTimesCalled(int NewValue, char *WhichUser) {
311         char buf[256];
312         sprintf(buf, "%d", NewValue);
313         CtdlErrno = CtdlInternalGetUserParam(buf, 3, WhichUser);
314         return(CtdlErrno);
315         }
316
317 int CtdlGetUserMessagesPosted(char *WhichUser) {
318         char buf[256];
319         CtdlErrno = CtdlInternalGetUserParam(buf, 4, WhichUser);
320         return((CtdlErrno == 0) ? atoi(buf) : (-1));
321         }
322
323 int CtdlSetUserMessagesPosted(int NewValue, char *WhichUser) {
324         char buf[256];
325         sprintf(buf, "%d", NewValue);
326         CtdlErrno = CtdlInternalGetUserParam(buf, 4, WhichUser);
327         return(CtdlErrno);
328         }
329
330 int CtdlGetUserAccessLevel(char *WhichUser) {
331         char buf[256];
332         CtdlErrno = CtdlInternalGetUserParam(buf, 5, WhichUser);
333         return((CtdlErrno == 0) ? atoi(buf) : (-1));
334         }
335
336 int CtdlSetUserAccessLevel(int NewValue, char *WhichUser) {
337         char buf[256];
338
339         if ( (NewValue < 1) || (NewValue > 6) ) {
340                 return(ERROR + ILLEGAL_VALUE);
341                 }
342
343         sprintf(buf, "%d", NewValue);
344         CtdlErrno = CtdlInternalGetUserParam(buf, 5, WhichUser);
345         return(CtdlErrno);
346         }
347
348 long CtdlGetUserNumber(char *WhichUser) {
349         char buf[256];
350         CtdlErrno = CtdlInternalGetUserParam(buf, 6, WhichUser);
351         return((CtdlErrno == 0) ? atol(buf) : (-1L));
352         }
353
354 int CtdlSetUserNumber(long NewValue, char *WhichUser) {
355         char buf[256];
356         sprintf(buf, "%ld", NewValue);
357         CtdlErrno = CtdlInternalGetUserParam(buf, 6, WhichUser);
358         return(CtdlErrno);
359         }
360
361 time_t CtdlGetUserLastCall(char *WhichUser) {
362         char buf[256];
363         CtdlErrno = CtdlInternalGetUserParam(buf, 7, WhichUser);
364         return((CtdlErrno == 0) ? atol(buf) : (time_t)(-1L));
365         }
366
367 int CtdlSetUserLastCall(time_t NewValue, char *WhichUser) {
368         char buf[256];
369         sprintf(buf, "%ld", NewValue);
370         CtdlErrno = CtdlInternalGetUserParam(buf, 7, WhichUser);
371         return(CtdlErrno);
372         }
373
374 int CtdlForEachUser(int (*CallBack)(char *EachUser))  {
375         struct CtdlInternalList *TheList = NULL;
376         struct CtdlInternalList *ptr;
377         char buf[256];
378
379         serv_puts("LIST");
380         serv_gets(buf);
381         if (buf[0] != '1') return(-1);
382
383         while (serv_gets(buf), strcmp(buf, "000")) {
384                 ptr = (struct CtdlInternalList *)
385                         malloc(sizeof (struct CtdlInternalList));
386                 if (ptr != NULL) {
387                         CtdlInternalExtract(ptr->data, buf, 0);
388                         ptr->next = TheList;
389                         TheList = ptr;
390                         }
391                 }
392
393         while (TheList != NULL) {
394                 (*CallBack)(TheList->data);
395                 ptr = TheList->next;
396                 free(TheList);
397                 TheList = ptr;
398                 }
399
400         return(0);
401         }