X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwho.c;h=834eb48177259bcf13cf88a245d99f1caa1a722b;hb=2362c3d4de86f20822ab81015222a196137fd20e;hp=f5de0ddf32a0f0302ac571a8fa9c420550e53120;hpb=c477d6a73cf3afdc47913e2c775ceb5938b6a469;p=citadel.git diff --git a/webcit/who.c b/webcit/who.c index f5de0ddf3..834eb4817 100644 --- a/webcit/who.c +++ b/webcit/who.c @@ -1,23 +1,124 @@ /* * $Id$ */ -/** - * \defgroup DislpayWho Display a list of all users currently logged on to the Citadel server. - * \ingroup WebcitDisplayItems - */ -/*@{*/ + #include "webcit.h" +typedef struct UserStateStruct { + char *UserName; + long UserNameLen; + char *Room; + long RoomLen; + char *Host; + long HostLen; + char *RealRoom; + long RealRoomLen; + char *RealHost; + long RealHostLen; + long LastActive; + int Session; + int Idle; + int SessionCount; +} UserStateStruct; + +void DestroyUserStruct(void *vUser) +{ + UserStateStruct *User = (UserStateStruct*) vUser; + free(User->UserName); + free(User->Room); + free(User->Host); + free(User->RealRoom); + free(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(User1->UserName, User2->UserName); +} -/** - * \brief Display inner div of Wholist - */ -void who_inner_div(void) { + +int GetWholistSection(HashList *List, time_t now) +{ + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + UserStateStruct *User, *OldUser; + void *VOldUser; char buf[SIZ], user[SIZ], room[SIZ], host[SIZ], realroom[SIZ], realhost[SIZ]; - int sess; - time_t last_activity; + size_t BufLen; + + serv_puts("RWHO"); + serv_getln(buf, sizeof buf); + if (buf[0] == '1') { + while (BufLen = serv_getln(buf, sizeof buf), strcmp(buf, "000")) { + if (BufLen <= 0) + continue; + User = (UserStateStruct*) malloc(sizeof(UserStateStruct)); + User->Session = extract_int(buf, 0); + + User->UserNameLen = extract_token(user, buf, 1, '|', sizeof user); + User->UserName = malloc(User->UserNameLen + 1); + memcpy(User->UserName, user, User->UserNameLen + 1); + + User->RoomLen = extract_token(room, buf, 2, '|', sizeof room); + User->Room = malloc(User->RoomLen + 1); + memcpy(User->Room, room, User->RoomLen + 1); + + User->HostLen = extract_token(host, buf, 3, '|', sizeof host); + User->Host = malloc(User->HostLen + 1); + memcpy(User->Host, host, User->HostLen + 1); + + User->RealRoomLen = extract_token(realroom, buf, 9, '|', sizeof realroom); + User->RealRoom = malloc(User->RealRoomLen + 1); + memcpy(User->RealRoom, realroom, User->RealRoomLen + 1); + + User->RealHostLen = extract_token(realhost, buf, 10, '|', sizeof realhost); + User->RealHost = malloc(User->RealHostLen + 1); + memcpy(User->RealHost, realhost, User->RealHostLen + 1); + + User->LastActive = extract_long(buf, 5); + User->Idle = (now - User->LastActive) > 900L; + User->SessionCount = 1; + + if (GetHash(List, User->UserName, User->UserNameLen, &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, User->UserName, User->UserNameLen, User, DestroyUserStruct); + } + SortByPayload(List, CompareUserStruct); + return 1; + } + else + return 0; +} + +/* + * Display inner div of Wholist + */ +void who_inner_div(void) { + UserStateStruct *User; + void *VUser; + char buf[SIZ]; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + HashList *List; + HashPos *it; + char *UserName; + long len; time_t now; int bg = 0; @@ -31,6 +132,7 @@ void who_inner_div(void) { serv_puts("TIME"); serv_getln(buf, sizeof buf); + if (buf[0] == '2') { now = extract_long(&buf[4], 0); } @@ -38,18 +140,12 @@ void who_inner_div(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 ? "even" : "odd") @@ -57,19 +153,19 @@ void who_inner_div(void) { wprintf(""); - if ((WC->is_aide) && - (sess != WC->ctdl_pid)) { - wprintf(" is_aide) && + (User->Session != WCC->ctdl_pid)) { + wprintf(" Session); wprintf("\" onClick=\"return ConfirmKill();\">%s", _("(kill)")); } - if (sess == WC->ctdl_pid) { + if (User->Session == WCC->ctdl_pid) { wprintf(" %s", _("(edit)")); } wprintf(""); - /** (link to page this user) */ - wprintf("UserName); wprintf("\">" " "); wprintf(""); - /** (idle flag) */ - wprintf(""); - if ((now - last_activity) > 900L) { + /* (idle flag) */ + wprintf(""); + if (User->Idle) { wprintf(" " ""); + "alt=\"(%s %ld %s)\" border=\"0\" />", + _("idle since"), + (now - User->LastActive) / 60, + _("Minutes") + ); + } else { wprintf(" " @@ -93,41 +194,44 @@ void who_inner_div(void) { } wprintf("\n"); - - - /** username (link to user bio/photo page) */ + /* username (link to user bio/photo page) */ wprintf("UserName); wprintf("\">"); - escputs(user); + escputs(User->UserName); + if (User->SessionCount > 1) + wprintf(" [%d] ", User->SessionCount); wprintf(""); - /** room */ + /* room */ wprintf("\n\t"); - escputs(room); - if (!IsEmptyStr(realroom) ) { + escputs(User->Room); + if (!IsEmptyStr(User->RealRoom) ) { wprintf("
"); - escputs(realroom); + escputs(User->RealRoom); wprintf(""); } wprintf("\n\t"); - /** hostname */ - escputs(host); - if (!IsEmptyStr(realhost)) { + /* hostname */ + escputs(User->Host); + if (!IsEmptyStr(User->RealHost)) { wprintf("
"); - escputs(realhost); + escputs(User->RealHost); wprintf(""); } wprintf("\n"); } + DeleteHashPos(&it); } wprintf(""); + DeleteHash(&List); + } -/** - * \brief who is on? +/* + * Display a list of users currently logged in to the system */ void who(void) { @@ -143,34 +247,37 @@ void who(void) ); wprintf("
\n"); - wprintf("
"); - wprintf("\""); - wprintf(" "); - + wprintf("
"); + wprintf(""); + wprintf("

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

"); + wprintf(""); + wprintf("
    \n"); + wprintf("
  • "); offer_start_page(); - wprintf("
\n"); - wprintf("
\n"); - - wprintf("
\n"); + wprintf(""); + 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("
\n"); + wprintf("
"); - 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"); + 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 @@ -179,15 +286,15 @@ void who(void) */ wprintf( " \n" ); wDumpContent(1); } -/** - * \brief end session \todo what??? does this belong here? +/* + * end session */ void terminate_session(void) { @@ -199,26 +306,26 @@ void terminate_session(void) } -/** - * \brief Change your session info (fake roomname and hostname) +/* + * Change your session info (fake roomname and hostname) */ void edit_me(void) { char buf[SIZ]; - if (!IsEmptyStr(bstr("change_room_name_button"))) { + if (havebstr("change_room_name_button")) { serv_printf("RCHG %s", bstr("fake_roomname")); serv_getln(buf, sizeof buf); http_redirect("who"); - } else if (!IsEmptyStr(bstr("change_host_name_button"))) { + } else if (havebstr("change_host_name_button")) { serv_printf("HCHG %s", bstr("fake_hostname")); serv_getln(buf, sizeof buf); http_redirect("who"); - } else if (!IsEmptyStr(bstr("change_user_name_button"))) { + } else if (havebstr("change_user_name_button")) { serv_printf("UCHG %s", bstr("fake_username")); serv_getln(buf, sizeof buf); http_redirect("who"); - } else if (!IsEmptyStr(bstr("cancel_button"))) { + } else if (havebstr("cancel_button")) { http_redirect("who"); } else { output_headers(1, 1, 0, 0, 0, 0); @@ -238,7 +345,7 @@ void edit_me(void) wprintf("
\n"); wprintf("
\n"); - wprintf("\n", WC->nonce); + wprintf("\n", WC->nonce); wprintf("\n"); @@ -279,5 +386,51 @@ void edit_me(void) } } +/* + * Wholist section + */ +void wholist_section(void) { + UserStateStruct *User; + void *VUser; + HashList *List; + HashPos *it; + char *UserName; + long len; + 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); + + if (GetWholistSection(List, now)) { + SortByPayload(List, CompareUserStruct); + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &UserName, &VUser)) { + User = VUser; + if (strcmp(User->UserName, NLI)) { + wprintf("
  • Idle) { + wprintf("inactiveuser"); + } + else { + wprintf("activeuser"); + } + wprintf("\">UserName); + wprintf("\">"); + escputs(User->UserName); + wprintf("
  • "); + } + } + DeleteHashPos(&it); + } + DeleteHash(&List); +}