WHQ: templatize editing of user; fix handling of output after edit.
[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)
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 (GetHash(List, 
86                                     ChrPtr(User->UserName), 
87                                     StrLength(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                                     ChrPtr(User->UserName), 
103                                     StrLength(User->UserName), 
104                                     User, DestroyUserStruct);
105                 }
106                 SortByPayload(List, CompareUserStruct);
107                 return 1;
108         }
109         else {
110                 return 0;
111         }
112 }
113
114 /*
115  * end session
116  */
117 void terminate_session(void)
118 {
119         char buf[SIZ];
120
121         serv_printf("TERM %s", bstr("which_session"));
122         serv_getln(buf, sizeof buf);
123         url_do_template();
124 }
125
126
127 /*
128  * Change your session info (fake roomname and hostname)
129  */
130 void edit_me(void)
131 {
132         char buf[SIZ];
133
134         output_headers(1, 0, 0, 0, 0, 0);
135         if (havebstr("change_room_name_button")) {
136                 serv_printf("RCHG %s", bstr("fake_roomname"));
137                 serv_getln(buf, sizeof buf);
138                 do_template("who");
139         } else if (havebstr("change_host_name_button")) {
140                 serv_printf("HCHG %s", bstr("fake_hostname"));
141                 serv_getln(buf, sizeof buf);
142                 do_template("who");
143         } else if (havebstr("change_user_name_button")) {
144                 serv_printf("UCHG %s", bstr("fake_username"));
145                 serv_getln(buf, sizeof buf);
146                 do_template("who");
147         } else if (havebstr("cancel_button")) {
148                 do_template("who");
149         } else {
150                 do_template("who_edit");
151         }
152         end_burst();
153 }
154
155 void _terminate_session(void) {
156         slrp_highest();
157         terminate_session();
158 }
159
160 HashList *GetWholistHash(StrBuf *Target, WCTemplputParams *TP)
161
162 {
163         StrBuf *Buf;
164         HashList *List;
165         time_t now;
166
167         Buf = NewStrBuf();
168
169         serv_puts("TIME");
170         StrBuf_ServGetln(Buf);
171         if (GetServerStatus(Buf, NULL)  == 2) {
172                 const char *pos = ChrPtr(Buf) + 4;
173                 now = StrBufExtractNext_long(Buf, &pos, '|');
174         }
175         else {
176                 now = time(NULL);
177         }
178
179         List = NewHash(1, NULL);
180         GetWholistSection(List, now, Buf);
181         FreeStrBuf(&Buf);
182         return List;
183 }
184
185
186 void DeleteWholistHash(HashList **KillMe)
187 {
188         DeleteHash(KillMe);
189 }
190
191 void tmplput_who_username(StrBuf *Target, WCTemplputParams *TP)
192 {
193         UserStateStruct *User = (UserStateStruct*) CTX;
194         StrBufAppendTemplate(Target, TP, User->UserName, 0);
195 }
196
197 void tmplput_who_room(StrBuf *Target, WCTemplputParams *TP)
198 {
199         UserStateStruct *User = (UserStateStruct*) CTX;
200         StrBufAppendTemplate(Target, TP, User->Room, 0);
201 }
202
203 void tmplput_who_host(StrBuf *Target, WCTemplputParams *TP)
204 {
205         UserStateStruct *User = (UserStateStruct*) CTX;
206         StrBufAppendTemplate(Target, TP, User->Host, 0);
207 }
208
209 void tmplput_who_realroom(StrBuf *Target, WCTemplputParams *TP)
210 {
211         UserStateStruct *User = (UserStateStruct*) CTX;
212         StrBufAppendTemplate(Target, TP, User->RealRoom, 0);
213 }
214 int conditional_who_realroom(StrBuf *Target, WCTemplputParams *TP)
215 {
216         UserStateStruct *User = (UserStateStruct*) CTX;
217         return StrLength(User->RealRoom) > 0;
218 }
219
220 void tmplput_who_realhost(StrBuf *Target, WCTemplputParams *TP)
221 {
222         UserStateStruct *User = (UserStateStruct*) CTX;
223         StrBufAppendTemplate(Target, TP, User->RealHost, 0);
224 }
225 int conditional_who_realhost(StrBuf *Target, WCTemplputParams *TP)
226 {
227         UserStateStruct *User = (UserStateStruct*) CTX;
228         return StrLength(User->RealHost) > 0;
229 }
230
231 void tmplput_who_lastactive(StrBuf *Target, WCTemplputParams *TP)
232 {
233         UserStateStruct *User = (UserStateStruct*) CTX;
234         StrBufAppendPrintf(Target, "%d", User->LastActive);
235 }
236
237 void tmplput_who_idlesince(StrBuf *Target, WCTemplputParams *TP)
238 {
239         UserStateStruct *User = (UserStateStruct*) CTX;
240         StrBufAppendPrintf(Target, "%d", User->IdleSince);
241 }
242
243 void tmplput_who_session(StrBuf *Target, WCTemplputParams *TP)
244 {
245         UserStateStruct *User = (UserStateStruct*) CTX;
246         StrBufAppendPrintf(Target, "%d", User->Session);
247 }
248
249 int conditional_who_idle(StrBuf *Target, WCTemplputParams *TP)
250 {
251         UserStateStruct *User = (UserStateStruct*) CTX;
252         return User->Idle;
253 }
254
255 int conditional_who_nsessions(StrBuf *Target, WCTemplputParams *TP)
256 {
257         UserStateStruct *User = (UserStateStruct*) CTX;
258         return User->SessionCount;
259 }
260
261 void tmplput_who_nsessions(StrBuf *Target, WCTemplputParams *TP)
262 {
263         UserStateStruct *User = (UserStateStruct*) CTX;
264         StrBufAppendPrintf(Target, "%d", User->SessionCount);
265 }
266
267 int conditional_who_isme(StrBuf *Target, WCTemplputParams *TP)
268 {
269         UserStateStruct *User = (UserStateStruct*) CTX;
270         return (User->Session == WC->ctdl_pid);
271 }
272
273 void 
274 InitModule_WHO
275 (void)
276 {
277         
278
279         WebcitAddUrlHandler(HKEY("terminate_session"), "", 0, _terminate_session, 0);
280         WebcitAddUrlHandler(HKEY("edit_me"), "", 0, edit_me, 0);
281
282         RegisterIterator("WHOLIST", 0, NULL, GetWholistHash, NULL, DeleteWholistHash, CTX_WHO, CTX_NONE, IT_NOFLAG);
283
284         RegisterNamespace("WHO:NAME",        0, 1, tmplput_who_username, NULL, CTX_WHO);
285         RegisterNamespace("WHO:ROOM",        0, 1, tmplput_who_room, NULL, CTX_WHO);
286         RegisterNamespace("WHO:HOST",        0, 1, tmplput_who_host, NULL, CTX_WHO);
287         RegisterNamespace("WHO:REALROOM",    0, 1, tmplput_who_realroom, NULL, CTX_WHO);
288         RegisterNamespace("WHO:REALHOST",    0, 1, tmplput_who_realhost, NULL, CTX_WHO);
289         RegisterNamespace("WHO:LASTACTIVE",  0, 1, tmplput_who_lastactive, NULL, CTX_WHO);
290         RegisterNamespace("WHO:IDLESINCE",   0, 1, tmplput_who_idlesince, NULL, CTX_WHO);
291         RegisterNamespace("WHO:SESSION",     0, 1, tmplput_who_session, NULL, CTX_WHO);
292         RegisterNamespace("WHO:NSESSIONS",   0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
293         RegisterNamespace("WHO:NSESSIONS",   0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
294
295         RegisterConditional(HKEY("WHO:IDLE"),      1, conditional_who_idle, CTX_WHO);
296         RegisterConditional(HKEY("WHO:NSESSIONS"), 1, conditional_who_nsessions, CTX_WHO);
297         RegisterConditional(HKEY("WHO:ISME"),      1, conditional_who_isme, CTX_WHO);
298         RegisterConditional(HKEY("WHO:REALROOM"),  1, conditional_who_realroom, CTX_WHO);
299         RegisterConditional(HKEY("WHO:REALHOST"),  1, conditional_who_realhost, CTX_WHO);
300 }