X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwho.c;h=00a06fdb0164581a0f71301b4ef6b2f3a737e1c5;hb=f0d4dec106f607b5bbd5bb1cf1467c55ffefa8c8;hp=2ae652dd4722cacab62ebdbc00104a3e83f0355e;hpb=b212ca36f2db6271ebc2bcae4584575888a350ba;p=citadel.git diff --git a/webcit/who.c b/webcit/who.c index 2ae652dd4..00a06fdb0 100644 --- a/webcit/who.c +++ b/webcit/who.c @@ -1,179 +1,309 @@ -/* $Id$ */ - -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#include -#include -#include +/* + * $Id$ + */ + #include "webcit.h" -#include "child.h" -struct whouser { - struct whouser *next; - int sessionnum; - char username[256]; - char roomname[256]; - char hostname[256]; - char clientsoftware[256]; -}; +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; -/* - * who is on? - */ -void whobbs(void) +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); +} + + +int GetWholistSection(HashList *List, time_t now) { - struct whouser *wlist = NULL; - struct whouser *wptr = NULL; - char buf[256], sess, user[256], room[256], host[256]; - int foundit; - - printf("HTTP/1.0 200 OK\n"); - output_headers(1); - - wprintf("
"); - wprintf("Users currently on "); - escputs(serv_info.serv_humannode); - wprintf("
\n"); - - wprintf("
\n\n\n"); - wprintf("\n"); - wprintf("\n"); - wprintf(""); - wprintf("\n\n"); + 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]; + size_t BufLen; + serv_puts("RWHO"); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '1') { - while (serv_gets(buf), strcmp(buf, "000")) { - sess = extract_int(buf, 0); - extract(user, buf, 1); - extract(room, buf, 2); - extract(host, buf, 3); - - foundit = 0; - for (wptr = wlist; wptr != NULL; wptr = wptr->next) { - if (wptr->sessionnum == sess) { - foundit = 1; - if (strcasecmp(user, wptr->username)) { - sprintf(buf, "%cBR%c%s", - LB, RB, user); - strcat(wptr->username, buf); - } - if (strcasecmp(room, wptr->roomname)) { - sprintf(buf, "%cBR%c%s", - LB, RB, room); - strcat(wptr->roomname, buf); - } - if (strcasecmp(host, wptr->hostname)) { - sprintf(buf, "%cBR%c%s", - LB, RB, host); - strcat(wptr->hostname, buf); - } + 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; +} - if (foundit == 0) { - wptr = (struct whouser *) - malloc(sizeof(struct whouser)); - wptr->next = wlist; - wlist = wptr; - strcpy(wlist->username, user); - strcpy(wlist->roomname, room); - strcpy(wlist->hostname, host); - wlist->sessionnum = sess; +/* + * 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; + const char *UserName; + long len; + time_t now; + int bg = 0; + + wprintf("
Session IDUser NameRoomFrom host
" + "\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); + } + else { + now = time(NULL); + } + + 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") + ); + + + wprintf(""); + + /* (link to page this user) */ + wprintf(""); - while (wlist != NULL) { - wprintf("\n\t\n\t\n\n\t\n\t\n\t\n"); - wptr = wlist->next; - free(wlist); - wlist = wptr; + escputs(User->Host); + if (!IsEmptyStr(User->RealHost)) { + wprintf("
"); + escputs(User->RealHost); + wprintf(""); + } + wprintf("\n"); } + DeleteHashPos(&it); } - wprintf("
%s%s%s
"); + if ((WCC->is_aide) && + (User->Session != WCC->ctdl_pid)) { + wprintf(" Session); + wprintf("\" onClick=\"return ConfirmKill();\">%s", _("(kill)")); } - } + if (User->Session == WCC->ctdl_pid) { + wprintf(" %s", _("(edit)")); + } + wprintf("UserName); + wprintf("\">" + " "); + wprintf("
%d", wlist->sessionnum); - if ((is_aide) && - (wlist->sessionnum != serv_info.serv_pid)) { - wprintf(" sessionnum); - urlescputs(wlist->username); - wprintf("\">(kill)"); + /* (idle flag) */ + wprintf(""); + if (User->Idle) { + wprintf(" " + "", + _("idle since"), + (now - User->LastActive) / 60, + _("Minutes") + ); + } - if (wlist->sessionnum == serv_info.serv_pid) { - wprintf(" (edit)"); + else { + wprintf(" " + ""); } - /* username */ - wprintf("username); - wprintf("\" onMouseOver=\"window.status='View profile for "); - escputs(wlist->username); - wprintf("'; return true\">"); - escputs(wlist->username); - wprintf(""); + wprintf(""); + + /* username (link to user bio/photo page) */ + wprintf("UserName); + wprintf("\">"); + escputs(User->UserName); + if (User->SessionCount > 1) + wprintf(" [%d] ", User->SessionCount); + wprintf(""); + /* room */ - wprintf(""); - /* handle chat */ - if (strstr(wlist->roomname, "chat") != NULL) { - wprintf("<chat>"); - } else { - wprintf("roomname); - wprintf("\" onMouseOver=\"window.status='Go to room "); - escputs(wlist->roomname); - wprintf("'; return true\" TARGET=\"top\">"); - escputs(wlist->roomname); - wprintf(""); + wprintf(""); + escputs(User->Room); + if (!IsEmptyStr(User->RealRoom) ) { + wprintf("
"); + escputs(User->RealRoom); + wprintf(""); } - wprintf("
"); + wprintf(""); + /* hostname */ - escputs(wlist->hostname); - wprintf("
\n

\n"); - wprintf("\n\n
\n"); - wprintf("Refresh\n"); - wprintf("
\n
"); - wDumpContent(1); + wprintf(""); + DeleteHash(&List); + } -void terminate_session(void) +/* + * Display a list of users currently logged in to the system + */ +void who(void) { - char buf[256]; - - if (!strcasecmp(bstr("confirm"), "Yes")) { - serv_printf("TERM %s", bstr("which_session")); - serv_gets(buf); - if (buf[0] == '2') { - whobbs(); - } else { - display_error(&buf[4]); - } - } else { - printf("HTTP/1.0 200 OK\n"); - output_headers(1); - wprintf("
"); - wprintf("Confirm session termination"); - wprintf("
\n"); - - wprintf("Are you sure you want to terminate session %s", - bstr("which_session")); - if (strlen(bstr("session_owner")) > 0) { - wprintf(" ("); - escputs(bstr("session_owner")); - wprintf(")"); - } - wprintf("?

\n"); + char title[256]; - wprintf("", - bstr("which_session")); - wprintf("Yes   "); - wprintf("No
"); - wDumpContent(1); - } + 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); + who(); +} /* @@ -181,67 +311,142 @@ void terminate_session(void) */ void edit_me(void) { - char buf[256]; + char buf[SIZ]; - printf("HTTP/1.0 200 OK\n"); - output_headers(1); - - if (!strcasecmp(bstr("sc"), "Change room name")) { + if (havebstr("change_room_name_button")) { serv_printf("RCHG %s", bstr("fake_roomname")); - serv_gets(buf); - whobbs(); - } else if (!strcasecmp(bstr("sc"), "Change host name")) { + serv_getln(buf, sizeof buf); + http_redirect("who"); + } else if (havebstr("change_host_name_button")) { serv_printf("HCHG %s", bstr("fake_hostname")); - serv_gets(buf); - whobbs(); - } else if (!strcasecmp(bstr("sc"), "Change user name")) { + serv_getln(buf, sizeof buf); + http_redirect("who"); + } else if (havebstr("change_user_name_button")) { serv_printf("UCHG %s", bstr("fake_username")); - serv_gets(buf); - whobbs(); - } else if (!strcasecmp(bstr("sc"), "Cancel")) { - whobbs(); + serv_getln(buf, sizeof buf); + http_redirect("who"); + } else if (havebstr("cancel_button")) { + http_redirect("who"); } else { + output_headers(1, 1, 0, 0, 0, 0); - wprintf("
"); - wprintf(""); - wprintf("Edit your session display"); - wprintf("
\n"); - wprintf(""); - 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("
\n
\n"); - - wprintf("
\n"); - - wprintf("\n"); - - wprintf("\n\n\n\n"); - - wprintf("\n\n\n"); - - if (is_aide) { - wprintf("\n\n\n"); - } - wprintf("
Room name:"); - wprintf("\n"); - wprintf(""); - wprintf(""); - wprintf("
Host name:"); - wprintf("\n"); - wprintf(""); - wprintf(""); - wprintf("
User name:"); - wprintf("\n"); - wprintf(""); - wprintf(""); - wprintf("
  "); - wprintf(""); - wprintf("
\n"); + wprintf("
\n"); + wprintf("
"); + wprintf(""); + wprintf(_("Edit your session display")); + wprintf("
\n"); + wprintf("
\n
\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", WC->nonce); + + wprintf("\n"); - wprintf("\n"); + wprintf("\n\n\n\n"); + + wprintf("\n\n\n"); + + if (WC->is_aide) { + 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("
"); + wprintf(_("User name:")); + wprintf(""); + wprintf("\n"); + wprintf(""); + wprintf("", + _("Change user name")); + wprintf("
"); + wprintf("", + _("Cancel")); + wprintf("
\n"); + wprintf("\n"); wDumpContent(1); } } + +/* + * 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; + + 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); +} + +void _terminate_session(void) { + slrp_highest(); + terminate_session(); +} + +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); +}