ac30cc72dd2e040fdc4d2ac212ea10bf692649fb
[citadel.git] / webcit / who.c
1
2 #include "webcit.h"
3
4 typedef struct UserStateStruct {
5         StrBuf *UserName;
6         StrBuf *Room;
7         StrBuf *Host;
8         StrBuf *RealRoom;
9         StrBuf *RealHost;
10         long LastActive;
11         int Session;
12         int Idle;
13         int IdleSince;
14         int SessionCount;
15 } UserStateStruct;
16
17 void DestroyUserStruct(void *vUser)
18 {
19         UserStateStruct *User = (UserStateStruct*) vUser;
20         FreeStrBuf(&User->UserName);
21         FreeStrBuf(&User->Room);
22         FreeStrBuf(&User->Host);
23         FreeStrBuf(&User->RealRoom);
24         FreeStrBuf(&User->RealHost);
25         free(User);
26 }
27
28 int CompareUserStruct(const void *VUser1, const void *VUser2)
29 {
30         const UserStateStruct *User1 = (UserStateStruct*) GetSearchPayload(VUser1);
31         const UserStateStruct *User2 = (UserStateStruct*) GetSearchPayload(VUser2);
32         
33         if (User1->Idle != User2->Idle)
34                 return User1->Idle > User2->Idle;
35         return strcasecmp(ChrPtr(User1->UserName), 
36                           ChrPtr(User2->UserName));
37 }
38
39
40 int GetWholistSection(HashList *List, time_t now, StrBuf *Buf, const char *FilterName, long FNLen)
41 {
42         wcsession *WCC = WC;
43         UserStateStruct *User, *OldUser;
44         void *VOldUser;
45         size_t BufLen;
46         const char *Pos;
47
48         serv_puts("RWHO");
49         StrBuf_ServGetln(Buf);
50         if (GetServerStatus(Buf, NULL) == 1) {
51                 while (BufLen = StrBuf_ServGetln(Buf), 
52                        ((BufLen >= 0) && 
53                         ((BufLen != 3) || strcmp(ChrPtr(Buf), "000"))))
54                 {
55                         if (BufLen <= 0)
56                             continue;
57                         Pos = NULL;
58                         User = (UserStateStruct*) malloc(sizeof(UserStateStruct));
59                         User->Session = StrBufExtractNext_int(Buf, &Pos, '|');
60
61                         User->UserName = NewStrBufPlain(NULL, BufLen);
62                         StrBufExtract_NextToken(User->UserName, Buf, &Pos, '|');
63                         
64                         User->Room = NewStrBufPlain(NULL, BufLen);
65                         StrBufExtract_NextToken(User->Room, Buf, &Pos, '|');
66
67                         User->Host = NewStrBufPlain(NULL, BufLen);
68                         StrBufExtract_NextToken(User->Host, Buf, &Pos, '|');
69
70                         StrBufSkip_NTokenS(Buf, &Pos, '|', 1);
71
72                         User->LastActive = StrBufExtractNext_long(Buf, &Pos, '|');
73                         StrBufSkip_NTokenS(Buf, &Pos, '|', 3);
74
75                         User->RealRoom = NewStrBufPlain(NULL, BufLen);
76                         StrBufExtract_NextToken(User->RealRoom, Buf, &Pos, '|');
77
78                         User->RealHost = NewStrBufPlain(NULL, BufLen);
79                         StrBufExtract_NextToken(User->RealHost, Buf, &Pos, '|');
80                         
81                         User->Idle = (now - User->LastActive) > 900L;
82                         User->IdleSince = (now - User->LastActive) / 60;
83                         User->SessionCount = 1;
84
85                         if (FilterName == NULL) {
86                                 if (GetHash(List, 
87                                             SKEY(User->UserName), 
88                                             &VOldUser)) {
89                                         OldUser = VOldUser;
90                                         OldUser->SessionCount++;
91                                         if (!User->Idle) {
92                                                 if (User->Session == WCC->ctdl_pid) 
93                                                         OldUser->Session = User->Session;
94                                                 
95                                                 OldUser->Idle = User->Idle;
96                                                 OldUser->LastActive = User->LastActive;
97                                         }
98                                         DestroyUserStruct(User);
99                                 }
100                                 else
101                                         Put(List, 
102                                             SKEY(User->UserName), 
103                                             User, DestroyUserStruct);
104                         }
105                         else {
106                                 if (strcmp(FilterName, ChrPtr(User->UserName)) == 0)
107                                 {
108                                         Put(List, 
109                                             SKEY(User->UserName), 
110                                             User, DestroyUserStruct);
111                                 }
112                                 else 
113                                 {
114                                         DestroyUserStruct(User);
115                                 }
116                         }
117                 }
118                 if (FilterName == NULL)
119                         SortByPayload(List, CompareUserStruct);
120                 return 1;
121         }
122         else {
123                 return 0;
124         }
125 }
126
127 /*
128  * end session
129  */
130 void terminate_session(void)
131 {
132         char buf[SIZ];
133
134         serv_printf("TERM %s", bstr("which_session"));
135         serv_getln(buf, sizeof buf);
136         url_do_template();
137 }
138
139
140 /*
141  * Change your session info (fake roomname and hostname)
142  */
143 void edit_me(void)
144 {
145         char buf[SIZ];
146
147         output_headers(1, 0, 0, 0, 0, 0);
148         if (havebstr("change_room_name_button")) {
149                 serv_printf("RCHG %s", bstr("fake_roomname"));
150                 serv_getln(buf, sizeof buf);
151                 do_template("who");
152         } else if (havebstr("change_host_name_button")) {
153                 serv_printf("HCHG %s", bstr("fake_hostname"));
154                 serv_getln(buf, sizeof buf);
155                 do_template("who");
156         } else if (havebstr("change_user_name_button")) {
157                 serv_printf("UCHG %s", bstr("fake_username"));
158                 serv_getln(buf, sizeof buf);
159                 do_template("who");
160         } else if (havebstr("cancel_button")) {
161                 do_template("who");
162         } else {
163                 do_template("who_edit");
164         }
165         end_burst();
166 }
167
168 void _terminate_session(void) {
169         slrp_highest();
170         terminate_session();
171 }
172
173 HashList *GetWholistHash(StrBuf *Target, WCTemplputParams *TP)
174
175 {
176         const char *ch = NULL;
177         int HashUniq = 1;
178         long len;
179         StrBuf *FilterNameStr = NULL;
180         StrBuf *Buf;
181         HashList *List;
182         time_t now;
183
184         Buf = NewStrBuf();
185
186         serv_puts("TIME");
187         StrBuf_ServGetln(Buf);
188         if (GetServerStatus(Buf, NULL)  == 2) {
189                 const char *pos = ChrPtr(Buf) + 4;
190                 now = StrBufExtractNext_long(Buf, &pos, '|');
191         }
192         else {
193                 now = time(NULL);
194         }
195         if (HaveTemplateTokenString(NULL, TP, 2, &ch, &len))
196         {
197                 FilterNameStr = NewStrBuf();
198                 GetTemplateTokenString(FilterNameStr, TP, 2, &ch, &len);
199                 HashUniq = 0;
200         }
201
202         List = NewHash(HashUniq, NULL);
203         GetWholistSection(List, now, Buf, ch, len);
204         FreeStrBuf(&Buf);
205         FreeStrBuf(&FilterNameStr);
206         return List;
207 }
208
209
210 void DeleteWholistHash(HashList **KillMe)
211 {
212         DeleteHash(KillMe);
213 }
214
215 void tmplput_who_username(StrBuf *Target, WCTemplputParams *TP)
216 {
217         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
218         StrBufAppendTemplate(Target, TP, User->UserName, 0);
219 }
220
221 void tmplput_who_room(StrBuf *Target, WCTemplputParams *TP)
222 {
223         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
224         StrBufAppendTemplate(Target, TP, User->Room, 0);
225 }
226
227 void tmplput_who_host(StrBuf *Target, WCTemplputParams *TP)
228 {
229         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
230         StrBufAppendTemplate(Target, TP, User->Host, 0);
231 }
232
233 void tmplput_who_realroom(StrBuf *Target, WCTemplputParams *TP)
234 {
235         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
236         StrBufAppendTemplate(Target, TP, User->RealRoom, 0);
237 }
238 int conditional_who_realroom(StrBuf *Target, WCTemplputParams *TP)
239 {
240         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
241         return StrLength(User->RealRoom) > 0;
242 }
243
244 void tmplput_who_realhost(StrBuf *Target, WCTemplputParams *TP)
245 {
246         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
247         StrBufAppendTemplate(Target, TP, User->RealHost, 0);
248 }
249 int conditional_who_realhost(StrBuf *Target, WCTemplputParams *TP)
250 {
251         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
252         return StrLength(User->RealHost) > 0;
253 }
254
255 void tmplput_who_lastactive(StrBuf *Target, WCTemplputParams *TP)
256 {
257         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
258         StrBufAppendPrintf(Target, "%d", User->LastActive);
259 }
260
261 void tmplput_who_idlesince(StrBuf *Target, WCTemplputParams *TP)
262 {
263         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
264         StrBufAppendPrintf(Target, "%d", User->IdleSince);
265 }
266
267 void tmplput_who_session(StrBuf *Target, WCTemplputParams *TP)
268 {
269         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
270         StrBufAppendPrintf(Target, "%d", User->Session);
271 }
272
273 int conditional_who_idle(StrBuf *Target, WCTemplputParams *TP)
274 {
275         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
276         return User->Idle;
277 }
278
279 int conditional_who_nsessions(StrBuf *Target, WCTemplputParams *TP)
280 {
281         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
282         return User->SessionCount;
283 }
284
285 void tmplput_who_nsessions(StrBuf *Target, WCTemplputParams *TP)
286 {
287         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
288         StrBufAppendPrintf(Target, "%d", User->SessionCount);
289 }
290
291 int conditional_who_isme(StrBuf *Target, WCTemplputParams *TP)
292 {
293         UserStateStruct *User = (UserStateStruct*) CTX(CTX_WHO);
294         return (User->Session == WC->ctdl_pid);
295 }
296
297 void 
298 InitModule_WHO
299 (void)
300 {
301         
302
303         WebcitAddUrlHandler(HKEY("terminate_session"), "", 0, _terminate_session, 0);
304         WebcitAddUrlHandler(HKEY("edit_me"), "", 0, edit_me, 0);
305
306         RegisterIterator("WHOLIST", 1, NULL, GetWholistHash, NULL, DeleteWholistHash, CTX_WHO, CTX_NONE, IT_NOFLAG);
307
308         RegisterNamespace("WHO:NAME",        0, 1, tmplput_who_username, NULL, CTX_WHO);
309         RegisterNamespace("WHO:ROOM",        0, 1, tmplput_who_room, NULL, CTX_WHO);
310         RegisterNamespace("WHO:HOST",        0, 1, tmplput_who_host, NULL, CTX_WHO);
311         RegisterNamespace("WHO:REALROOM",    0, 1, tmplput_who_realroom, NULL, CTX_WHO);
312         RegisterNamespace("WHO:REALHOST",    0, 1, tmplput_who_realhost, NULL, CTX_WHO);
313         RegisterNamespace("WHO:LASTACTIVE",  0, 1, tmplput_who_lastactive, NULL, CTX_WHO);
314         RegisterNamespace("WHO:IDLESINCE",   0, 1, tmplput_who_idlesince, NULL, CTX_WHO);
315         RegisterNamespace("WHO:SESSION",     0, 1, tmplput_who_session, NULL, CTX_WHO);
316         RegisterNamespace("WHO:NSESSIONS",   0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
317         RegisterNamespace("WHO:NSESSIONS",   0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
318
319         RegisterConditional(HKEY("WHO:IDLE"),      1, conditional_who_idle, CTX_WHO);
320         RegisterConditional(HKEY("WHO:NSESSIONS"), 1, conditional_who_nsessions, CTX_WHO);
321         RegisterConditional(HKEY("WHO:ISME"),      1, conditional_who_isme, CTX_WHO);
322         RegisterConditional(HKEY("WHO:REALROOM"),  1, conditional_who_realroom, CTX_WHO);
323         RegisterConditional(HKEY("WHO:REALHOST"),  1, conditional_who_realhost, CTX_WHO);
324 }