From d8abfc1ab880919a13cfc012427eab7ee0363334 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sun, 2 Mar 2008 14:20:45 +0000 Subject: [PATCH] * make server_getln return the number of bytes it read * sort Phonebook popup alphabeticaly * sort Olson-Timezones alphabeticaly * sort Who Is Online views first by Idle/Active then alphabetical * move wholist_section summary.c -> who.c so we can easily use the above algorithms --- webcit/addressbook_popup.c | 69 +++++++++--- webcit/siteconfig.c | 28 +++-- webcit/summary.c | 41 -------- webcit/tcp_sockets.c | 3 +- webcit/webcit.h | 4 +- webcit/who.c | 209 +++++++++++++++++++++++++++++++------ 6 files changed, 258 insertions(+), 96 deletions(-) diff --git a/webcit/addressbook_popup.c b/webcit/addressbook_popup.c index 91641482c..add472740 100644 --- a/webcit/addressbook_popup.c +++ b/webcit/addressbook_popup.c @@ -28,7 +28,10 @@ void address_book_popup(void) { */ void display_address_book_middle_div(void) { char buf[256]; - char ebuf[256]; + long len; + char *Name, *Namee; + HashList *List; + HashPos *it; begin_ajax_response(); @@ -46,18 +49,29 @@ void display_address_book_middle_div(void) { escputs(serv_info.serv_humannode); wprintf("\n"); + + List = NewHash(); serv_puts("LKRA"); serv_getln(buf, sizeof buf); - if (buf[0] == '1') while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) { + if (buf[0] == '1') while(len = serv_getln(buf, sizeof buf), strcmp(buf, "000")) { if (extract_int(buf, 6) == VIEW_ADDRESSBOOK) { - extract_token(ebuf, buf, 0, '|', sizeof ebuf); - wprintf("\n"); + Name = (char*) malloc(len + 1); + len = extract_token(Name, buf, 0, '|', len); + Put(List, Name, len, Name, NULL); } } + + SortByHashKey(List); + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &Name, (void**)&Namee)) { + wprintf("\n"); + } + DeleteHashPos(&it); + DeleteHash(&List); wprintf(""); wprintf(""); @@ -82,29 +96,42 @@ void display_address_book_middle_div(void) { */ void display_address_book_inner_div() { char buf[256]; - char username[256]; int num_targets = 0; char target_id[64]; char target_label[64]; + long len; + char *Name, *Namee; + HashList *List; + HashPos *it; int i; char saved_roomname[128]; begin_ajax_response(); + List = NewHash(); wprintf("
" "\n"); - sprintf(&general[strlen(general)], "\n", - (!strcasecmp(buf, "UTC") ? "selected" : "") - ); - icalarray *zones; int z; + long len; char this_zone[128]; + char *ZName, *ZNamee; + HashList *List; + HashPos *it; + + List = NewHash(); + len = sizeof("UTC") + 1; + ZName = malloc(len + 1); + memcpy(ZName, "UTC", len + 1); + Put(List, ZName, len, ZName, NULL); zones = icaltimezone_get_builtin_timezones(); for (z = 0; z < zones->num_elements; ++z) { strcpy(this_zone, icaltimezone_get_location(icalarray_element_at(zones, z))); + len = strlen(this_zone); + ZName = (char*)malloc(len +1); + memcpy(ZName, this_zone, len + 1); + Put(List, ZName, len, ZName, NULL); + } + SortByHashKey(List); + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &ZName, (void**)&ZNamee)) { sprintf(&general[strlen(general)], "\n", - (!strcasecmp(this_zone, buf) ? "selected" : ""), - this_zone, this_zone + (!strcasecmp(ZName, buf) ? "selected" : ""), + ZName, ZName ); } + DeleteHashPos(&it); + DeleteHash(&List); sprintf(&general[strlen(general)], ""); sprintf(&general[strlen(general)], "\n"); diff --git a/webcit/summary.c b/webcit/summary.c index 06487fb9f..e8072e5fd 100644 --- a/webcit/summary.c +++ b/webcit/summary.c @@ -74,47 +74,6 @@ void new_messages_section(void) { } -/** - * \brief Wholist section - */ -void wholist_section(void) { - char buf[SIZ]; - char user[SIZ]; - time_t last_activity; - 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); - } - - serv_puts("RWHO"); - serv_getln(buf, sizeof buf); - if (buf[0] == '1') while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - extract_token(user, buf, 1, '|', sizeof user); - last_activity = extract_long(buf, 5); - if (strcmp(user, NLI)) { - wprintf("
  • 900L) { - wprintf("inactiveuser"); - } - else { - wprintf("activeuser"); - } - wprintf("\">"); - escputs(user); - wprintf("
  • "); - } - } -} - - /** * \brief Task list section */ diff --git a/webcit/tcp_sockets.c b/webcit/tcp_sockets.c index 59cfcdd7a..d03672eac 100644 --- a/webcit/tcp_sockets.c +++ b/webcit/tcp_sockets.c @@ -149,7 +149,7 @@ void serv_read(char *buf, int bytes) /** * \brief input string from pipe */ -void serv_getln(char *strbuf, int bufsize) +int serv_getln(char *strbuf, int bufsize) { int ch, len; char buf[2]; @@ -167,6 +167,7 @@ void serv_getln(char *strbuf, int bufsize) #ifdef SERV_TRACE lprintf(9, "%3d>%s\n", WC->serv_sock, strbuf); #endif + return len; } diff --git a/webcit/webcit.h b/webcit/webcit.h index 5cd36956c..316e841da 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -126,7 +126,7 @@ extern locale_t wc_locales[]; #define CLIENT_ID 4 #define CLIENT_VERSION 730 /* This version of WebCit */ #define MINIMUM_CIT_VERSION 730 /* min required Citadel ver */ -#define LIBCITADEL_MIN 107 /* min required libcitadel ver */ +#define LIBCITADEL_MIN 108 /* min required libcitadel ver */ #define DEFAULT_HOST "localhost" /* Default Citadel server */ #define DEFAULT_PORT "504" #define LB (1) /* Internal escape chars */ @@ -490,7 +490,7 @@ void ungoto(void); void get_serv_info(char *, char *); int uds_connectsock(char *); int tcp_connectsock(char *, char *); -void serv_getln(char *strbuf, int bufsize); +int serv_getln(char *strbuf, int bufsize); void serv_puts(char *string); void who(void); void who_inner_div(void); diff --git a/webcit/who.c b/webcit/who.c index d1e05518f..95ba557cd 100644 --- a/webcit/who.c +++ b/webcit/who.c @@ -9,15 +9,113 @@ #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); +} + + +int GetWholistSection(HashList *List, time_t now) +{ + UserStateStruct *User, *OldUser; + char buf[SIZ], user[SIZ], room[SIZ], host[SIZ], + realroom[SIZ], realhost[SIZ]; + 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")) { + 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, (void**)&OldUser)) { + OldUser->SessionCount++; + if (!User->Idle) { + 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; +} /** * \brief Display inner div of Wholist */ void who_inner_div(void) { - char buf[SIZ], user[SIZ], room[SIZ], host[SIZ], - realroom[SIZ], realhost[SIZ]; + UserStateStruct *User; + 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; int sess; - time_t last_activity; time_t now; int bg = 0; @@ -31,6 +129,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,17 +137,11 @@ 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(); + + if (GetWholistSection(List, now)) { + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &UserName, (void**)&User)) { bg = 1 - bg; wprintf("", @@ -57,19 +150,19 @@ void who_inner_div(void) { wprintf(""); - if ((WC->is_aide) && - (sess != WC->ctdl_pid)) { + if ((WCC->is_aide) && + (sess != WCC->ctdl_pid)) { wprintf(" %s", _("(kill)")); } - if (sess == WC->ctdl_pid) { + if (sess == WCC->ctdl_pid) { wprintf(" %s", _("(edit)")); } wprintf(""); /** (link to page this user) */ wprintf("UserName); wprintf("\">" ""); - if ((now - last_activity) > 900L) { + if (User->Idle) { wprintf(" " ""); + "alt=\"(%s %d %s)\" border=\"0\" />", + _("idle since"), + (now - User->LastActive) / 60, + _("Minutes") + ); + } else { wprintf(" " @@ -93,36 +191,39 @@ void who_inner_div(void) { } wprintf("\n"); - - /** 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 */ 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)) { + escputs(User->Host); + if (!IsEmptyStr(User->RealHost)) { wprintf("
    "); - escputs(realhost); + escputs(User->RealHost); wprintf(""); } wprintf("\n"); } + DeleteHashPos(&it); } wprintf(""); + DeleteHash(&List); + } @@ -282,5 +383,53 @@ void edit_me(void) } } +/** + * \brief Wholist section + */ +void wholist_section(void) { + UserStateStruct *User; + 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(); + + if (GetWholistSection(List, now)) { + SortByPayload(List, CompareUserStruct); + it = GetNewHashPos(); + while (GetNextHashPos(List, it, &len, &UserName, (void**)&User)) { + if (strcmp(User->UserName, NLI)) { + wprintf("
  • Idle) { + wprintf("inactiveuser"); + } + else { + wprintf("activeuser"); + } + wprintf("\">UserName); + wprintf("\">"); + escputs(User->UserName); + wprintf("
  • "); + } + } + DeleteHashPos(&it); + } + DeleteHash(&List); +} + + /*@}*/ -- 2.30.2