4 CtxType CTX_WHO = CTX_NONE;
6 typedef struct UserStateStruct {
20 void DestroyUserStruct(void *vUser) {
21 UserStateStruct *User = (UserStateStruct *) vUser;
22 FreeStrBuf(&User->UserName);
23 FreeStrBuf(&User->Room);
24 FreeStrBuf(&User->Host);
25 FreeStrBuf(&User->RealRoom);
26 FreeStrBuf(&User->RealHost);
27 FreeStrBuf(&User->UserAgent);
31 int CompareUserStruct(const void *VUser1, const void *VUser2) {
32 const UserStateStruct *User1 = (UserStateStruct *) GetSearchPayload(VUser1);
33 const UserStateStruct *User2 = (UserStateStruct *) GetSearchPayload(VUser2);
35 if (User1->Idle != User2->Idle)
36 return User1->Idle > User2->Idle;
37 return strcasecmp(ChrPtr(User1->UserName), ChrPtr(User2->UserName));
41 int GetWholistSection(HashList * List, time_t now, StrBuf * Buf, const char *FilterName, long FNLen) {
42 UserStateStruct *User, *OldUser;
48 StrBuf_ServGetln(Buf);
49 if (GetServerStatus(Buf, NULL) == 1) {
50 while (BufLen = StrBuf_ServGetln(Buf), ((BufLen >= 0) && ((BufLen != 3) || strcmp(ChrPtr(Buf), "000")))) {
54 User = (UserStateStruct *) malloc(sizeof(UserStateStruct));
55 User->Session = StrBufExtractNext_int(Buf, &Pos, '|');
57 User->UserName = NewStrBufPlain(NULL, BufLen);
58 StrBufExtract_NextToken(User->UserName, Buf, &Pos, '|');
60 User->Room = NewStrBufPlain(NULL, BufLen);
61 StrBufExtract_NextToken(User->Room, Buf, &Pos, '|');
63 User->Host = NewStrBufPlain(NULL, BufLen);
64 StrBufExtract_NextToken(User->Host, Buf, &Pos, '|');
66 User->UserAgent = NewStrBufPlain(NULL, BufLen);
67 StrBufExtract_NextToken(User->UserAgent, Buf, &Pos, '|');
69 User->LastActive = StrBufExtractNext_long(Buf, &Pos, '|');
70 StrBufSkip_NTokenS(Buf, &Pos, '|', 3);
72 User->RealRoom = NewStrBufPlain(NULL, BufLen);
73 StrBufExtract_NextToken(User->RealRoom, Buf, &Pos, '|');
75 User->RealHost = NewStrBufPlain(NULL, BufLen);
76 StrBufExtract_NextToken(User->RealHost, Buf, &Pos, '|');
78 User->Idle = (now - User->LastActive) > 900L;
79 User->IdleSince = (now - User->LastActive) / 60;
80 User->SessionCount = 1;
82 if (FilterName == NULL) {
83 if (GetHash(List, SKEY(User->UserName), &VOldUser)) {
85 OldUser->SessionCount++;
87 if (User->Session == WC->ctdl_pid)
88 OldUser->Session = User->Session;
90 OldUser->Idle = User->Idle;
91 OldUser->LastActive = User->LastActive;
93 DestroyUserStruct(User);
96 Put(List, SKEY(User->UserName), User, DestroyUserStruct);
99 if (strcmp(FilterName, ChrPtr(User->UserName)) == 0) {
100 Put(List, SKEY(User->UserName), User, DestroyUserStruct);
103 DestroyUserStruct(User);
107 if (FilterName == NULL)
108 SortByPayload(List, CompareUserStruct);
119 void terminate_session(void) {
122 serv_printf("TERM %s", bstr("which_session"));
123 serv_getln(buf, sizeof buf);
128 void _terminate_session(void) {
133 HashList *GetWholistHash(StrBuf * Target, WCTemplputParams * TP) {
134 const char *ch = NULL;
137 StrBuf *FilterNameStr = NULL;
145 StrBuf_ServGetln(Buf);
146 if (GetServerStatus(Buf, NULL) == 2) {
147 const char *pos = ChrPtr(Buf) + 4;
148 now = StrBufExtractNext_long(Buf, &pos, '|');
153 if (HaveTemplateTokenString(NULL, TP, 2, &ch, &len)) {
154 FilterNameStr = NewStrBuf();
155 GetTemplateTokenString(FilterNameStr, TP, 2, &ch, &len);
159 List = NewHash(HashUniq, NULL);
160 GetWholistSection(List, now, Buf, ch, len);
162 FreeStrBuf(&FilterNameStr);
167 void DeleteWholistHash(HashList ** KillMe) {
171 void tmplput_who_username(StrBuf * Target, WCTemplputParams * TP) {
172 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
173 StrBufAppendTemplate(Target, TP, User->UserName, 0);
176 void tmplput_who_UserAgent(StrBuf * Target, WCTemplputParams * TP) {
177 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
178 StrBufAppendTemplate(Target, TP, User->UserAgent, 0);
181 void tmplput_who_room(StrBuf * Target, WCTemplputParams * TP) {
182 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
183 StrBufAppendTemplate(Target, TP, User->Room, 0);
186 void tmplput_who_host(StrBuf * Target, WCTemplputParams * TP) {
187 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
188 StrBufAppendTemplate(Target, TP, User->Host, 0);
191 void tmplput_who_realroom(StrBuf * Target, WCTemplputParams * TP) {
192 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
193 StrBufAppendTemplate(Target, TP, User->RealRoom, 0);
195 int conditional_who_realroom(StrBuf * Target, WCTemplputParams * TP) {
196 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
197 return StrLength(User->RealRoom) > 0;
200 void tmplput_who_realhost(StrBuf * Target, WCTemplputParams * TP) {
201 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
202 StrBufAppendTemplate(Target, TP, User->RealHost, 0);
204 int conditional_who_realhost(StrBuf * Target, WCTemplputParams * TP) {
205 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
206 return StrLength(User->RealHost) > 0;
209 void tmplput_who_lastactive(StrBuf * Target, WCTemplputParams * TP) {
210 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
211 StrBufAppendPrintf(Target, "%d", User->LastActive);
214 void tmplput_who_idlesince(StrBuf * Target, WCTemplputParams * TP) {
215 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
216 StrBufAppendPrintf(Target, "%d", User->IdleSince);
219 void tmplput_who_session(StrBuf * Target, WCTemplputParams * TP) {
220 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
221 StrBufAppendPrintf(Target, "%d", User->Session);
224 int conditional_who_idle(StrBuf * Target, WCTemplputParams * TP) {
225 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
229 int conditional_who_nsessions(StrBuf * Target, WCTemplputParams * TP) {
230 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
231 return User->SessionCount;
234 void tmplput_who_nsessions(StrBuf * Target, WCTemplputParams * TP) {
235 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
236 StrBufAppendPrintf(Target, "%d", User->SessionCount);
239 int conditional_who_isme(StrBuf * Target, WCTemplputParams * TP) {
240 UserStateStruct *User = (UserStateStruct *) CTX(CTX_WHO);
241 return (User->Session == WC->ctdl_pid);
244 void InitModule_WHO(void) {
245 RegisterCTX(CTX_WHO);
247 WebcitAddUrlHandler(HKEY("terminate_session"), "", 0, _terminate_session, 0);
249 RegisterIterator("WHOLIST", 1, NULL, GetWholistHash, NULL, DeleteWholistHash, CTX_WHO, CTX_NONE, IT_NOFLAG);
251 RegisterNamespace("WHO:NAME", 0, 1, tmplput_who_username, NULL, CTX_WHO);
252 RegisterNamespace("WHO:USERAGENT", 0, 1, tmplput_who_UserAgent, NULL, CTX_WHO);
253 RegisterNamespace("WHO:ROOM", 0, 1, tmplput_who_room, NULL, CTX_WHO);
254 RegisterNamespace("WHO:HOST", 0, 1, tmplput_who_host, NULL, CTX_WHO);
255 RegisterNamespace("WHO:REALROOM", 0, 1, tmplput_who_realroom, NULL, CTX_WHO);
256 RegisterNamespace("WHO:REALHOST", 0, 1, tmplput_who_realhost, NULL, CTX_WHO);
257 RegisterNamespace("WHO:LASTACTIVE", 0, 1, tmplput_who_lastactive, NULL, CTX_WHO);
258 RegisterNamespace("WHO:IDLESINCE", 0, 1, tmplput_who_idlesince, NULL, CTX_WHO);
259 RegisterNamespace("WHO:SESSION", 0, 1, tmplput_who_session, NULL, CTX_WHO);
260 RegisterNamespace("WHO:NSESSIONS", 0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
261 RegisterNamespace("WHO:NSESSIONS", 0, 1, tmplput_who_nsessions, NULL, CTX_WHO);
263 RegisterConditional("WHO:IDLE", 1, conditional_who_idle, CTX_WHO);
264 RegisterConditional("WHO:NSESSIONS", 1, conditional_who_nsessions, CTX_WHO);
265 RegisterConditional("WHO:ISME", 1, conditional_who_isme, CTX_WHO);
266 RegisterConditional("WHO:REALROOM", 1, conditional_who_realroom, CTX_WHO);
267 RegisterConditional("WHO:REALHOST", 1, conditional_who_realhost, CTX_WHO);