]> code.citadel.org Git - citadel.git/blob - libCxClient/src/users.c
Initial revision
[citadel.git] / libCxClient / src / users.c
1 /**
2  ** libCxClient - Citadel/UX Extensible Client API
3  ** Copyright (c) 2000, Flaming Sword Productions
4  ** Copyright (c) 2001, The Citadel/UX Consortium
5  ** All Rights Reserved
6  **
7  ** Module: users.o
8  ** Date: 2000-10-15
9  ** Last Revision: 2000-10-15
10  ** Description: Functions which manipulate user lists. (who's online, Directory, etc.)
11  ** CVS: $Id$
12  **/
13 #include        <stdio.h>
14 #include        <stdlib.h>
15 #include        <stdarg.h>
16 #include        <string.h>
17 #include        <CxClient.h>
18 #include        "autoconf.h"
19
20 /**
21  ** CxUsOnline(fmt): List online users.
22  ** [fmt]: Format of list you are expecting to receive:
23  ** 0: (Default) Session ID|User|Room
24  **/
25 CXLIST          CxUsOnline(int fmt) {
26 CXLIST          toret = 0;
27 int             rc;
28 char            buf[255];
29
30         DPF((DFA,"Retrieving online user list"));
31         CxClSend("RWHO");
32         rc = CxClRecv(buf);
33
34         /**
35          ** The session protocol specs say that
36          ** this process will never return anything
37          ** but LISTING_FOLLOWS.  I don't belive it. ;)
38          **/
39         if( CHECKRC(rc, RC_LISTING) ) {
40
41                 do {
42                         rc = CxClRecv(buf);
43                         DPF((DFA,"[%d] %s",rc,buf));
44
45                         if( rc ) {
46                                 toret = (CXLIST)CxLlInsert(toret,buf);
47                         }
48
49                 } while(rc<0);
50
51                 return(toret);
52
53         /**
54          ** In the event that the moon IS made of
55          ** green cheese.......
56          **/
57         } else {
58                 DPF((DFA,"Session spec violation!! IG!!! AUGH!!!"));
59                 return(toret);
60         }
61
62         return(NULL);
63 }
64
65 /**
66  ** CxUsList(): Fetch the Global Address Book.
67  **/
68 CXLIST          CxUsList() {
69 CXLIST          toret = 0;
70 int             rc;
71 char            buf[512];
72
73         DPF((DFA,"Requesting user list..."));
74         CxClSend("LIST");
75         rc = CxClRecv(buf);
76         if( CHECKRC(rc, RC_LISTING) ) {
77                 do {
78                         rc = CxClRecv(buf);
79                         if(rc) {
80                                 toret = CxLlInsert(toret,buf);
81                         }
82                 } while(rc < 0);
83         }
84
85         return(toret);
86 }
87
88 /**
89  ** CxUsAuth(): Authenticate a username/password combination.  If we're
90  ** already logged in, then we need to abort this.  [How can we tell if
91  ** we are??]
92  **
93  ** [Expects]
94  **  (char *) uname: Username we wish to verify
95  **  (char *) passwd: Password of this user.
96  **
97  ** [Returns]
98  **  On Success: USERINFO: User Information structure. [*]
99  **  On Failure: NULL
100  **/
101 USERINFO        *CxUsAuth(const char *uname, const char *passwd) {
102 USERINFO        *user_info;
103 char            *xmit, buf[512], *g_Ser[20];
104 int             rc;
105
106         DPF((DFA,"Authenticating '%s'",uname));
107         xmit = (char *)CxMalloc(strlen(uname)+6);
108         sprintf(xmit,"USER %s",uname);
109         CxClSend(xmit);
110         CxFree(xmit);
111
112         DPF((DFA,"Validating username"));
113         rc = CxClRecv(buf);
114         DPF((DFA,"%d", rc));
115         if( CHECKRC(rc, RC_MOREDATA) ) {
116                 xmit = (char *)CxMalloc(strlen(passwd)+6);
117                 sprintf(xmit,"PASS %s",passwd);
118                 CxClSend(xmit);
119                 CxFree(xmit);
120
121                 DPF((DFA,"Validating password"));
122                 rc = CxClRecv(buf);
123
124                 /**
125                  ** RETURN: Authentication information O.K.
126                  **/
127                 if( CHECKRC(rc, RC_OK) ) {
128                         user_info = (USERINFO *)CxMalloc(sizeof(USERINFO));
129
130                         CxSerialize(buf, &g_Ser);
131                         strcpy(user_info->username, g_Ser[0]);
132                         user_info->system.access_level = atoi(g_Ser[1]);
133                         user_info->system.times_called = atol(g_Ser[2]);
134                         user_info->system.messages_posted = atol(g_Ser[3]);
135                         user_info->system.user_flags = atol(g_Ser[4]);
136                         user_info->system.user_number = atol(g_Ser[5]);
137                         DPF((DFA,"MEM/MDA:\t-1\t@0x%08x (Needs manual deallocation)", user_info));
138                         
139                         return(user_info);
140
141                 /**
142                  ** RETURN: Invalid password.
143                  **/
144                 } else {
145                         return(NULL);
146                 }
147
148         /**
149          ** RETURN: Invalid username
150          **/
151         } else {
152                 return(NULL);
153         }
154
155         /**
156          ** SHOULD be unreachable...
157          **/
158         return(NULL);
159 }
160
161 /**
162  ** CxUsCreate(): Create a user account.
163  **
164  ** [Expects]
165  **  USERINFO user: Populated USERINFO structure.
166  **
167  ** [Returns]
168  **  On Success: 0
169  **  On Failure: 1 - Not enough information
170  **              2 - USER ALREADY EXISTS
171  **/
172 int             CxUsCreate(USERINFO user) {
173 char            buf[512];
174 int             rc;
175
176         /**
177          ** RETURN: Not enough information.
178          **/
179         if(!user.username[0] || !user.password[0]) return(1);
180
181         /**
182          ** Phase 1: Create new account.
183          **/
184         DPF((DFA,"Creating user account '%s'", user.username));
185
186         sprintf(buf, "NEWU %s", user.username);
187         CxClSend(buf);
188         rc = CxClRecv(buf);
189
190         /**
191          ** RETURN: User already exists.
192          **/
193         if( CHECKRC(rc, RC_OK)) {
194                 return(2);
195         }
196
197         sprintf(buf, "SETP %s", user.password);
198         CxClSend(buf);
199         rc = CxClRecv(buf);
200
201         if( CHECKRC(rc, RC_OK)) {
202                 return(0); /** Non-fatal error.  User just has a blank "" password. **/
203         }
204
205         /**
206          ** Phase 2: Populate registration structures on server.
207          **/
208         CxClSend("REGI");
209         rc = CxClRecv(buf);
210         if( CHECKRC(rc, RC_SENDLIST)) {
211                 sprintf(buf, "%s", user.fullname);
212                 CxClSend(buf);
213                 sprintf(buf, "%s", user.addr.street);
214                 CxClSend(buf);
215                 sprintf(buf, "%s", user.addr.city);
216                 CxClSend(buf);
217                 sprintf(buf, "%s", user.addr.st);
218                 CxClSend(buf);
219                 sprintf(buf, "%s", user.addr.zip);
220                 CxClSend(buf);
221                 sprintf(buf, "%s", user.contact.telephone);
222                 CxClSend(buf);
223                 sprintf(buf, "%s", user.contact.emailaddr);
224                 CxClSend(buf);
225                 CxClSend("000");
226         }
227
228         /**
229          ** Phase 3: Create personal rooms expected by CxClient.  [Please note that this will only work if
230          ** the server's default permissions allow new users to create rooms.  bbs.shadowcom.net will.]
231          **/
232         CxClSend("CRE8 0");
233         rc = CxClRecv(buf);
234         if( CHECKRC(rc, RC_OK)) {
235                 CxClSend("CRE8 1|My Schedule|4||");
236                 rc = CxClRecv(buf);
237                 printf("My Schedule: rc = %d", rc);
238                 CxClSend("CRE8 1|My Notes|4||");
239                 rc = CxClRecv(buf);
240                 printf("My Notes: rc = %d", rc);
241                 CxClSend("CRE8 1|My Tasks|4||");
242                 rc = CxClRecv(buf);
243                 printf("My Tasks: rc = %d", rc);
244                 CxClSend("CRE8 1|My Journal|4||");
245                 rc = CxClRecv(buf);
246                 printf("My Journal: rc = %d", rc);
247                 CxClSend("CRE8 1|My Contacts|4||");
248                 rc = CxClRecv(buf);
249                 printf("My Contacts: rc = %d", rc);
250         }
251
252         /**
253          ** RETURN: Success!
254          **/
255         return(0);
256 }