X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwho.c;h=0d78dee59eef68f95747068f6c467d80b0d5af95;hb=53c742f994c6d4a32b91c41ec92bc7abe8760df2;hp=6dd225f7c363d34b5765013d237f23f003c681cf;hpb=5e91a276d21a8386402e0a7444ac6a0301da924e;p=citadel.git diff --git a/webcit/who.c b/webcit/who.c index 6dd225f7c..0d78dee59 100644 --- a/webcit/who.c +++ b/webcit/who.c @@ -1,77 +1,139 @@ /* * $Id$ - * - * Display a list of all users currently logged on to the Citadel server. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "webcit.h" +typedef struct UserStateStruct { + StrBuf *UserName; + StrBuf *Room; + StrBuf *Host; + StrBuf *RealRoom; + StrBuf *RealHost; + long LastActive; + int Session; + int Idle; + int SessionCount; +} UserStateStruct; + +void DestroyUserStruct(void *vUser) +{ + UserStateStruct *User = (UserStateStruct*) vUser; + FreeStrBuf(&User->UserName); + FreeStrBuf(&User->Room); + FreeStrBuf(&User->Host); + FreeStrBuf(&User->RealRoom); + FreeStrBuf(&User->RealHost); + free(User); +} +int CompareUserStruct(const void *VUser1, const void *VUser2) +{ + const UserStateStruct *User1 = (UserStateStruct*) GetSearchPayload(VUser1); + const UserStateStruct *User2 = (UserStateStruct*) GetSearchPayload(VUser2); + + if (User1->Idle != User2->Idle) + return User1->Idle > User2->Idle; + return strcasecmp(ChrPtr(User1->UserName), + ChrPtr(User2->UserName)); +} +int GetWholistSection(HashList *List, time_t now) +{ + StrBuf *Buf, *XBuf; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + UserStateStruct *User, *OldUser; + void *VOldUser; + size_t BufLen; + char buf[SIZ]; + serv_puts("RWHO"); + serv_getln(buf, sizeof buf); + if (buf[0] == '1') { + Buf = NewStrBuf(); + XBuf = NewStrBuf(); + while (BufLen = StrBuf_ServGetln(Buf), strcmp(ChrPtr(Buf), "000")) { + if (BufLen <= 0) + continue; + User = (UserStateStruct*) malloc(sizeof(UserStateStruct)); + User->Session = StrBufExtract_int(Buf, 0, '|'); + + StrBufExtract_token(XBuf, Buf, 1, '|'); + User->UserName = NewStrBufDup(XBuf); + + StrBufExtract_token(XBuf, Buf, 2, '|'); + User->Room = NewStrBufDup(XBuf); + + StrBufExtract_token(XBuf, Buf, 3, '|'); + User->Host = NewStrBufDup(XBuf); + + StrBufExtract_token(XBuf, Buf, 9, '|'); + User->RealRoom = NewStrBufDup(XBuf); + + StrBufExtract_token(XBuf, Buf, 10, '|'); + User->RealHost = NewStrBufDup(XBuf); + + User->LastActive = StrBufExtract_long(Buf, 5, '|'); + User->Idle = (now - User->LastActive) > 900L; + User->SessionCount = 1; + + if (GetHash(List, + ChrPtr(User->UserName), + StrLength(User->UserName), + &VOldUser)) { + OldUser = VOldUser; + OldUser->SessionCount++; + if (!User->Idle) { + if (User->Session == WCC->ctdl_pid) + OldUser->Session = User->Session; + + OldUser->Idle = User->Idle; + OldUser->LastActive = User->LastActive; + } + DestroyUserStruct(User); + } + else + Put(List, + ChrPtr(User->UserName), + StrLength(User->UserName), + User, DestroyUserStruct); + } + SortByPayload(List, CompareUserStruct); + + FreeStrBuf(&XBuf); + FreeStrBuf(&Buf); + return 1; + } + else + return 0; +} /* - * who is on? - */ -void whobbs(void) -{ - char buf[SIZ], user[SIZ], room[SIZ], host[SIZ], - realroom[SIZ], realhost[SIZ]; - int sess; - time_t last_activity; + * Display inner div of Wholist + * / +void who_inner_div(void) { + UserStateStruct *User; + void *VUser; + char buf[SIZ]; + struct wcsession *WCC = WC; + HashList *List; + HashPos *it; + const char *UserName; + long len; time_t now; int bg = 0; - - output_headers(1, 1, 2, 0, 1, 0, 0); - - wprintf("\n" - ); - - wprintf("
\n"); - wprintf("
"); - wprintf("\""); - wprintf(" Users currently on "); - escputs(serv_info.serv_humannode); - wprintf(""); - offer_start_page(); - wprintf("
\n"); - wprintf("
\n" - "
\n"); - - wprintf("
" - "" + wprintf("
" "\n"); - wprintf("\n"); - wprintf("\n"); - wprintf(""); - wprintf("\n\n"); + wprintf("\n"); + wprintf("\n"); + wprintf("\n", _("User name")); + wprintf("", _("Room")); + wprintf("\n\n", _("From host")); serv_puts("TIME"); serv_getln(buf, sizeof buf); + if (buf[0] == '2') { now = extract_long(&buf[4], 0); } @@ -79,104 +141,171 @@ void whobbs(void) now = time(NULL); } - serv_puts("RWHO"); - serv_getln(buf, sizeof buf); - if (buf[0] == '1') { - while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - sess = extract_int(buf, 0); - extract_token(user, buf, 1, '|', sizeof user); - extract_token(room, buf, 2, '|', sizeof room); - extract_token(host, buf, 3, '|', sizeof host); - extract_token(realroom, buf, 9, '|', sizeof realroom); - extract_token(realhost, buf, 10, '|', sizeof realhost); - last_activity = extract_long(buf, 5); + List = NewHash(1, NULL); + if (GetWholistSection(List, now)) { + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &UserName, &VUser)) { + User = VUser; bg = 1 - bg; - wprintf("", - (bg ? "DDDDDD" : "FFFFFF") + wprintf("", + (bg ? "even" : "odd") ); - wprintf(""); + wprintf(""); - /* (link to page this user) */ - wprintf(""); - - /* (idle flag) */ - wprintf(""); + + / * (idle flag) * / + wprintf("\n\t\n\n\t\n\t\n\t\n\t\n"); + wprintf("\n"); } + DeleteHashPos(&it); } - wprintf("
 User NameRoomFrom host
%s%s%s
"); - if ((WC->is_aide) && - (sess != WC->ctdl_pid)) { - wprintf(" [kill]"); + wprintf(""); + if ((WCC->is_aide) && + (User->Session != WCC->ctdl_pid)) { + wprintf(" Session); + wprintf("\" onClick=\"return ConfirmKill();\">%s", _("(kill)")); } - if (sess == WC->ctdl_pid) { - wprintf(" [edit]"); + if (User->Session == WCC->ctdl_pid) { + wprintf(" %s", _("(edit)")); } - wprintf("UserName); wprintf("\">" - " "); - wprintf(""); - if ((now - last_activity) > 900L) { - wprintf(" " - ""); + " "); + wprintf(""); + if (User->Idle) { + wprintf(" " + "", + _("idle since"), + (now - User->LastActive) / 60, + _("Minutes") + ); + } - wprintf(""); - - + else { + wprintf(" " + ""); + } + wprintf(""); - /* username (link to user bio/photo page) */ - wprintf("UserName); wprintf("\">"); - escputs(user); - wprintf(""); - - /* room */ - wprintf(""); - escputs(room); - if (strlen(realroom) > 0) { - wprintf("
"); - escputs(realroom); - wprintf(""); + StrEscPuts(User->UserName); + if (User->SessionCount > 1) + wprintf(" [%d] ", User->SessionCount); + wprintf(""); + + / * room * / + wprintf("
"); + StrEscPuts(User->Room); + if (StrLength(User->RealRoom) > 0) { + wprintf("
"); + StrEscPuts(User->RealRoom); + wprintf(""); } - wprintf("
"); - - /* hostname */ - escputs(host); - if (strlen(realhost) > 0) { - wprintf("
"); - escputs(realhost); - wprintf(""); + wprintf("
"); + + / * hostname * / + StrEscPuts(User->Host); + if (StrLength(User->RealHost) > 0) { + wprintf("
"); + StrEscPuts(User->RealHost); + wprintf(""); } - wprintf("
\n" - "
" - "Click on a name to read user info. Click on " - "\"(p)\" to send " - "a page (instant message) to that user.
\n"); - wDumpContent(1); + wprintf(""); + DeleteHash(&List); } +*/ + + +/* + * Display a list of users currently logged in to the system + * / +void who(void) +{ + char title[256]; + + output_headers(1, 1, 2, 0, 0, 0); + wprintf("\n", _("Do you really want to kill this session?") + ); + wprintf("
\n"); + wprintf("
"); + wprintf(""); + wprintf("

"); + snprintf(title, sizeof title, _("Users currently on %s"), serv_info.serv_humannode); + escputs(title); + wprintf("

"); + wprintf("
    \n"); + wprintf("
  • "); + offer_start_page(); + wprintf("
"); + wprintf("
"); + + wprintf("
\n"); + wprintf("
"); + wprintf("
"); + snprintf(title, sizeof title, _("Users currently on %s"), serv_info.serv_humannode); + escputs(title); + wprintf("
"); + wprintf("
"); + wprintf("
"); + who_inner_div(); + wprintf("
"); + + wprintf("
"); + wprintf(_("Click on a name to read user info. Click on %s " + "to send an instant message to that user."), + "\"(p)\"" + ); + wprintf("
\n"); + + / * + * JavaScript to make the ajax refresh happen: + * See http://www.sergiopereira.com/articles/prototype.js.html for info on Ajax.PeriodicalUpdater + * It wants: 1. The div being updated + * 2. The URL of the update source + * 3. Other flags (such as the HTTP method and the refresh frequency) + * / + wprintf( + " \n" + ); + wDumpContent(1); +} +*/ + +/* + * end session + */ void terminate_session(void) { char buf[SIZ]; serv_printf("TERM %s", bstr("which_session")); serv_getln(buf, sizeof buf); - whobbs(); + ///who(); + url_do_template(); } @@ -187,66 +316,185 @@ void edit_me(void) { char buf[SIZ]; - if (!strcasecmp(bstr("sc"), "Change room name")) { + if (havebstr("change_room_name_button")) { serv_printf("RCHG %s", bstr("fake_roomname")); serv_getln(buf, sizeof buf); - http_redirect("/whobbs"); - } else if (!strcasecmp(bstr("sc"), "Change host name")) { + http_redirect("who"); + } else if (havebstr("change_host_name_button")) { serv_printf("HCHG %s", bstr("fake_hostname")); serv_getln(buf, sizeof buf); - http_redirect("/whobbs"); - } else if (!strcasecmp(bstr("sc"), "Change user name")) { + http_redirect("who"); + } else if (havebstr("change_user_name_button")) { serv_printf("UCHG %s", bstr("fake_username")); serv_getln(buf, sizeof buf); - http_redirect("/whobbs"); - } else if (!strcasecmp(bstr("sc"), "Cancel")) { - http_redirect("/whobbs"); + http_redirect("who"); + } else if (havebstr("cancel_button")) { + http_redirect("who"); } else { - - output_headers(1, 1, 0, 0, 0, 0, 0); + output_headers(1, 1, 0, 0, 0, 0); wprintf("
\n"); - wprintf("
"); - wprintf(""); - wprintf("Edit your session display"); - wprintf("
\n"); + wprintf("
"); + wprintf(""); + wprintf(_("Edit your session display")); + wprintf("
\n"); wprintf("
\n
\n"); - wprintf("This screen allows you to change the way your\n"); - wprintf("session appears in the 'Who is online' listing.\n"); - wprintf("To turn off any 'fake' name you've previously\n"); - wprintf("set, simply click the appropriate 'change' button\n"); - wprintf("without typing anything in the corresponding box.\n"); + wprintf(_("This screen allows you to change the way your " + "session appears in the 'Who is online' listing. " + "To turn off any 'fake' name you've previously " + "set, simply click the appropriate 'change' button " + "without typing anything in the corresponding box. ")); wprintf("
\n"); - wprintf("
\n"); + wprintf("\n"); + wprintf("\n", WC->nonce); + + wprintf("\n"); + + wprintf("\n\n\n\n"); + + wprintf("\n\n\n"); - wprintf("
"); + wprintf(_("Room name:")); + wprintf(""); + wprintf("\n"); + wprintf(""); + wprintf("", + _("Change room name")); + wprintf("
"); + wprintf(_("Host name:")); + wprintf(""); + wprintf("\n"); + wprintf(""); + wprintf("", + _("Change host name")); + wprintf("
\n"); + if (WC->is_aide) { + wprintf("\n\n\n"); + } + wprintf("
"); + wprintf(_("User name:")); + wprintf(""); + wprintf("\n"); + wprintf(""); + wprintf("", + _("Change user name")); + wprintf("
"); + wprintf("", + _("Cancel")); + wprintf("
\n"); + wprintf("
\n"); + wDumpContent(1); + } +} - wprintf("Room name:\n"); - wprintf("\n"); - wprintf("\n"); - wprintf(""); - wprintf("\n\n"); +/* + * Wholist section + * / +void wholist_section(void) { + UserStateStruct *User; + void *VUser; + HashList *List; + HashPos *it; + const char *UserName; + long len; + char buf[SIZ]; + time_t now; - wprintf("Host name:"); - wprintf("\n"); - wprintf("\n"); - wprintf(""); - wprintf("\n\n"); + serv_puts("TIME"); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + now = extract_long(&buf[4], 0); + } + else { + now = time(NULL); + } - if (WC->is_aide) { - wprintf("User name:"); - wprintf("\n"); - wprintf("\n"); - wprintf(""); - wprintf("\n\n"); + List = NewHash(1, NULL); + + if (GetWholistSection(List, now)) { + SortByPayload(List, CompareUserStruct); + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &UserName, &VUser)) { + User = VUser; + if (strcmp(ChrPtr(User->UserName), NLI)) { + wprintf("
  • Idle) { + wprintf("inactiveuser"); + } + else { + wprintf("activeuser"); + } + wprintf("\">UserName); + wprintf("\">"); + StrEscPuts(User->UserName); + wprintf("
  • "); + } } - wprintf("  "); - wprintf(""); - wprintf("\n"); + DeleteHashPos(&it); + } + DeleteHash(&List); +} +*/ - wprintf("\n"); - wDumpContent(1); +void _terminate_session(void) { + slrp_highest(); + terminate_session(); +} + +HashList *GetWholistHash(WCTemplateToken *Token) +{ + HashList *List; + char buf[SIZ]; + time_t now; + + serv_puts("TIME"); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + now = extract_long(&buf[4], 0); + } + else { + now = time(NULL); } + + List = NewHash(1, NULL); + GetWholistSection(List, now); + return List; +} + +void WholistSubst(StrBuf *TemplBuffer, void *vContext, WCTemplateToken *Token) +{ + UserStateStruct *User = (UserStateStruct*) vContext; + + SVPutBuf("WHO:NAME", User->UserName, 1); + SVPutBuf("WHO:ROOM", User->Room, 1); + SVPutBuf("WHO:HOST", User->Host, 1); + SVPutBuf("WHO:REALROOM", User->RealRoom, 1); + SVPutBuf("WHO:REALHOST", User->RealHost, 1); + svputlong("WHO:LASTACTIVE", User->LastActive); + ///svputlong("WHO:IDLESINCE",(now - User->LastActive) / 60);//// todo + svputlong("WHO:SESSION", User->Session); + svputlong("WHO:IDLE", User->Idle); + svputlong("WHO:NSESSIONS", User->SessionCount); + svputlong("WHO:ISME", (User->Session == WC->ctdl_pid)); +} + +void DeleteWholistHash(HashList *KillMe) +{ + DeleteHash(&KillMe); +} + +void +InitModule_WHO +(void) +{ +/// WebcitAddUrlHandler(HKEY("who"), who, 0); +// WebcitAddUrlHandler(HKEY("who_inner_html"), who_inner_div, AJAX); +// WebcitAddUrlHandler(HKEY("wholist_section"), wholist_section, AJAX); + WebcitAddUrlHandler(HKEY("terminate_session"), _terminate_session, 0); + WebcitAddUrlHandler(HKEY("edit_me"), edit_me, 0); + + RegisterIterator("WHOLIST", 0, NULL, GetWholistHash, WholistSubst, DeleteWholistHash); }