2 * Copyright (c) 1996-2011 by the citadel.org team
4 * This program is open source software. You can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "webserver.h"
24 * show a list of available users to edit them
25 * message the header message???
26 * preselect = which user should be selected in the browser
28 void select_user_to_edit(const char *preselect)
30 output_headers(1, 0, 0, 0, 1, 0);
31 do_template("aide_edituser_select");
36 typedef struct _UserListEntry {
45 /* Just available for Single users to view: */
52 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser, const char *Pos)
56 if (StrLength(SerializedUser) < 8)
59 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
60 ul->UserName = NewStrBuf();
61 ul->Passvoid = NewStrBuf();
63 StrBufExtract_NextToken(ul->UserName, SerializedUser, &Pos, '|');
64 StrBufExtract_NextToken(ul->Passvoid, SerializedUser, &Pos, '|');
65 ul->Flags = StrBufExtractNext_unsigned_long(SerializedUser, &Pos, '|');
66 ul->nLogons = StrBufExtractNext_int( SerializedUser, &Pos, '|');
67 ul->nPosts = StrBufExtractNext_int( SerializedUser, &Pos, '|');
68 ul->AccessLevel = StrBufExtractNext_int( SerializedUser, &Pos, '|');
69 ul->UID = StrBufExtractNext_int( SerializedUser, &Pos, '|');
70 ul->LastLogonT = StrBufExtractNext_long( SerializedUser, &Pos, '|');
71 ul->DaysTillPurge = StrBufExtractNext_int( SerializedUser, &Pos, '|');
75 void DeleteUserListEntry(void *vUserList)
77 UserListEntry *ul = (UserListEntry*) vUserList;
79 FreeStrBuf(&ul->UserName);
80 FreeStrBuf(&ul->Passvoid);
84 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
86 const char *Pos = NULL;
89 if (StrLength(SerializedUserList) < 8)
92 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
93 ul->UserName = NewStrBuf();
94 ul->Passvoid = NewStrBuf();
96 StrBufExtract_NextToken(ul->UserName, SerializedUserList, &Pos, '|');
97 ul->AccessLevel = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
98 ul->UID = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
99 ul->LastLogonT = StrBufExtractNext_long(SerializedUserList, &Pos, '|');
100 ul->nLogons = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
101 ul->nPosts = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
102 StrBufExtract_NextToken(ul->Passvoid, SerializedUserList, &Pos, '|');
104 ul->DaysTillPurge = -1;
111 int CompareUserListName(const void *vUser1, const void *vUser2)
113 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
114 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
116 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
119 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
121 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
122 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
123 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
126 int GroupchangeUserListName(const void *vUser1, const void *vUser2)
128 UserListEntry *u1 = (UserListEntry*) vUser1;
129 UserListEntry *u2 = (UserListEntry*) vUser2;
130 return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0];
134 * Sort by access level
136 int CompareAccessLevel(const void *vUser1, const void *vUser2)
138 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
139 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
141 return (u1->AccessLevel > u2->AccessLevel);
144 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
146 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
147 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
149 return (u2->AccessLevel > u1->AccessLevel);
152 int GroupchangeAccessLevel(const void *vUser1, const void *vUser2)
154 UserListEntry *u1 = (UserListEntry*) vUser1;
155 UserListEntry *u2 = (UserListEntry*) vUser2;
157 return u2->AccessLevel != u1->AccessLevel;
163 int CompareUID(const void *vUser1, const void *vUser2)
165 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
166 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
168 return (u1->UID > u2->UID);
171 int CompareUIDRev(const void *vUser1, const void *vUser2)
173 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
174 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
176 return (u2->UID > u1->UID);
179 int GroupchangeUID(const void *vUser1, const void *vUser2)
181 UserListEntry *u1 = (UserListEntry*) vUser1;
182 UserListEntry *u2 = (UserListEntry*) vUser2;
184 return (u2->UID / 10) != (u1->UID / 10);
188 * Sort By Date /// TODO!
190 int CompareLastLogon(const void *vUser1, const void *vUser2)
192 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
193 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
195 return (u1->LastLogonT > u2->LastLogonT);
198 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
200 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
201 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
203 return (u2->LastLogonT > u1->LastLogonT);
206 int GroupchangeLastLogon(const void *vUser1, const void *vUser2)
208 UserListEntry *u1 = (UserListEntry*) vUser1;
209 UserListEntry *u2 = (UserListEntry*) vUser2;
211 return (u2->LastLogonT != u1->LastLogonT);
215 * Sort By Number of Logons
217 int ComparenLogons(const void *vUser1, const void *vUser2)
219 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
220 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
222 return (u1->nLogons > u2->nLogons);
225 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
227 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
228 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
230 return (u2->nLogons > u1->nLogons);
233 int GroupchangenLogons(const void *vUser1, const void *vUser2)
235 UserListEntry *u1 = (UserListEntry*) vUser1;
236 UserListEntry *u2 = (UserListEntry*) vUser2;
238 return (u2->nLogons / 100) != (u1->nLogons / 100);
242 * Sort By Number of Posts
244 int ComparenPosts(const void *vUser1, const void *vUser2)
246 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
247 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
249 return (u1->nPosts > u2->nPosts);
252 int ComparenPostsRev(const void *vUser1, const void *vUser2)
254 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
255 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
257 return (u2->nPosts > u1->nPosts);
260 int GroupchangenPosts(const void *vUser1, const void *vUser2)
262 UserListEntry *u1 = (UserListEntry*) vUser1;
263 UserListEntry *u2 = (UserListEntry*) vUser2;
265 return (u2->nPosts / 100) != (u1->nPosts / 100);
269 HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP)
273 HashList *Hash = NULL;
279 WCTemplputParams SubTP;
281 memset(&SubTP, 0, sizeof(WCTemplputParams));
284 StrBuf_ServGetln(Buf);
285 if (GetServerStatus(Buf, NULL) == 1) {
286 Hash = NewHash(1, Flathash);
289 len = StrBuf_ServGetln(Buf);
292 !strcmp(ChrPtr(Buf), "000")))
297 ul = NewUserListEntry(Buf);
301 Put(Hash, IKEY(ul->UID), ul, DeleteUserListEntry);
305 if (GetServerStatus(Buf, NULL) == 1)
307 len = StrBuf_ServGetln(Buf);
310 !strcmp(ChrPtr(Buf), "000")))
315 UID = atoi(ChrPtr(Buf));
316 if (GetHash(Hash, IKEY(UID), &vData) && vData != 0)
318 ul = (UserListEntry*)vData;
322 SubTP.Filter.ContextType = CTX_USERLIST;
323 SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0);
325 SortByPayload(Hash, SortIt);
327 SortByPayload(Hash, CompareUID);
334 void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP)
336 UserListEntry *ul = (UserListEntry*) CTX;
337 StrBufAppendTemplate(Target, TP, ul->UserName, 0);
340 void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP)
342 UserListEntry *ul = (UserListEntry*) CTX;
343 StrBufAppendTemplate(Target, TP, ul->Passvoid, 0);
346 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
348 UserListEntry *ul = (UserListEntry*) CTX;
350 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
353 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
355 UserListEntry *ul = (UserListEntry*) CTX;
357 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
360 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
362 UserListEntry *ul = (UserListEntry*) CTX;
364 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
367 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
369 UserListEntry *ul = (UserListEntry*) CTX;
371 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
373 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
375 UserListEntry *ul = (UserListEntry*) CTX;
376 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
379 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
381 UserListEntry *ul = (UserListEntry*) CTX;
383 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
386 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
388 UserListEntry *ul = (UserListEntry*) CTX;
390 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
393 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
395 UserListEntry *ul = (UserListEntry*) CTX;
397 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
400 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
402 UserListEntry *ul = (UserListEntry*) CTX;
404 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
407 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
409 UserListEntry *ul = (UserListEntry*) CTX;
410 if (havebstr("usernum")) {
411 return ibstr("usernum") == ul->UID;
413 else if (havebstr("username")) {
414 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
420 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
422 UserListEntry *ul = (UserListEntry*) CTX;
423 return (ul->Flags & US_INTERNET) != 0;
426 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
428 UserListEntry *ul = (UserListEntry*) CTX;
433 return GetTemplateTokenNumber(Target,
440 int ConditionalHaveBIO(StrBuf *Target, WCTemplputParams *TP)
442 UserListEntry *ul = (UserListEntry*) CTX;
449 void tmplput_USER_BIO(StrBuf *Target, WCTemplputParams *TP)
456 GetTemplateTokenString(Target, TP, 0, &who, &len);
459 serv_printf("RBIO %s", who);
460 StrBuf_ServGetln(Buf);
461 if (GetServerStatus(Buf, NULL) == 1) {
462 StrBuf *BioBuf = NewStrBufPlain(NULL, SIZ);
463 while (!Done && StrBuf_ServGetln(Buf)>=0) {
464 if ( (StrLength(Buf)==3) &&
465 !strcmp(ChrPtr(Buf), "000"))
468 StrBufAppendBuf(BioBuf, Buf, 0);
470 StrBufAppendTemplate(Target, TP, BioBuf, 1);
476 int Conditional_USER_HAS_PIC(StrBuf *Target, WCTemplputParams *TP)
482 GetTemplateTokenString(Target, TP, 2, &who, &len);
485 serv_printf("OIMG _userpic_|%s", who);
486 StrBuf_ServGetln(Buf);
487 if (GetServerStatus(Buf, NULL) != 2) {
489 StrBuf_ServGetln(Buf);
490 GetServerStatus(Buf, NULL);
501 * Locate the message number of a user's vCard in the current room
502 * Returns the message id of his vcard
504 long locate_user_vcard_in_this_room(message_summary **VCMsg, wc_mime_attachment **VCAtt)
512 message_summary *Msg;
513 wc_mime_attachment *Att;
515 long vcard_msgnum = (-1L);
516 int already_tried_creating_one = 0;
517 StrBuf *FoundCharset = NewStrBuf();
518 StrBuf *Error = NULL;
519 SharedMessageStatus Stat;
524 memset(&Stat, 0, sizeof(SharedMessageStatus));
525 Stat.maxload = 10000;
526 Stat.lowest_found = (-1);
527 Stat.highest_found = (-1);
528 /* Search for the user's vCard */
529 if (load_msg_ptrs("MSGS ALL||||1", &Stat, NULL) > 0) {
530 at = GetNewHashPos(WCC->summ, 0);
531 while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
532 Msg = (message_summary*) vMsg;
533 Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
534 memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment));
535 Msg->MsgBody->msgnum = Msg->msgnum;
537 load_message(Msg, FoundCharset, &Error);
539 if (Msg->AllAttach != NULL) {
540 att = GetNewHashPos(Msg->AllAttach, 0);
541 while (GetNextHashPos(Msg->AllAttach, att, &HKLen, &HashKey, &vMsg) &&
542 (vcard_msgnum == -1)) {
543 Att = (wc_mime_attachment*) vMsg;
545 (strcasecmp(ChrPtr(Att->ContentType), "text/x-vcard") == 0)
546 || (strcasecmp(ChrPtr(Att->ContentType), "text/vcard") == 0)
550 vcard_msgnum = Msg->msgnum;
551 if (Att->Data == NULL) {
558 FreeStrBuf(&Error); /* don't care... */
564 /* If there's no vcard, create one */
565 if ((*VCMsg == NULL) && (already_tried_creating_one == 0)) {
567 already_tried_creating_one = 1;
568 serv_puts("ENT0 1|||4");
569 StrBuf_ServGetln(Buf);
570 if (GetServerStatus(Buf, NULL) == 4) {
571 serv_puts("Content-type: text/x-vcard");
573 serv_puts("begin:vcard");
574 serv_puts("end:vcard");
578 syslog(1, "Error while creating user vcard: %s\n", ChrPtr(Buf));
582 FreeStrBuf(&FoundCharset);
584 return(vcard_msgnum);
589 * Display the form for editing a user's address book entry
590 * username the name of the user
591 * usernum the citadel-uid of the user
593 void display_edit_address_book_entry(const char *username, long usernum) {
595 message_summary *VCMsg = NULL;
596 wc_mime_attachment *VCAtt = NULL;
599 long vcard_msgnum = (-1L);
601 /* Locate the user's config room, creating it if necessary */
603 roomname = NewStrBuf();
604 StrBufPrintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
605 serv_printf("GOTO %s||1", ChrPtr(roomname));
606 StrBuf_ServGetln(Buf);
607 if (GetServerStatus(Buf, NULL) != 2) {
608 serv_printf("CRE8 1|%s|5|||1|", ChrPtr(roomname));
609 StrBuf_ServGetln(Buf);
610 GetServerStatus(Buf, NULL);
611 serv_printf("GOTO %s||1", ChrPtr(roomname));
612 StrBuf_ServGetln(Buf);
613 if (GetServerStatus(Buf, NULL) != 2) {
614 FlushStrBuf(WCC->ImportantMsg);
615 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
616 select_user_to_edit(username);
618 FreeStrBuf(&roomname);
624 locate_user_vcard_in_this_room(&VCMsg, &VCAtt);
627 StrBufPlain(WCC->ImportantMsg,
628 _("An error occurred while trying to create or edit this address book entry."),
630 select_user_to_edit(username);
631 FreeStrBuf(&roomname);
635 do_edit_vcard(vcard_msgnum, "1",
638 "select_user_to_edit",
640 FreeStrBuf(&roomname);
644 void display_edituser(const char *supplied_username, int is_new) {
651 if (supplied_username != NULL) {
652 safestrncpy(username, supplied_username, sizeof username);
655 safestrncpy(username, bstr("username"), sizeof username);
659 serv_printf("AGUP %s", username);
660 StrBuf_ServGetln(Buf);
661 if (GetServerStatus(Buf, NULL) != 2) {
662 FlushStrBuf(WCC->ImportantMsg);
663 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
664 select_user_to_edit(username);
669 Pos = ChrPtr(Buf) + 4;
670 UL = NewUserListOneEntry(Buf, Pos);
671 if ((UL != NULL) && havebstr("edit_abe_button")) {
672 display_edit_address_book_entry(username, UL->UID);
674 else if ((UL != NULL) && havebstr("delete_button")) {
675 delete_user(username);
677 else if (UL != NULL) {
678 WCTemplputParams SubTP;
679 memset(&SubTP, 0, sizeof(WCTemplputParams));
680 SubTP.Filter.ContextType = CTX_USERLIST;
682 output_headers(1, 0, 0, 0, 1, 0);
683 DoTemplate(HKEY("aide_edituser_detailview"), NULL, &SubTP);
686 DeleteUserListEntry(UL);
693 * do the backend operation of the user edit on the server
695 void edituser(void) {
698 unsigned int flags = 0;
699 const char *username;
701 is_new = ibstr("is_new");
702 username = bstr("username");
704 if (!havebstr("ok_button")) {
705 StrBufPlain(WCC->ImportantMsg, _("Changes were not saved."), -1);
708 StrBuf *Buf = NewStrBuf();
710 flags = ibstr("flags");
711 if (yesbstr("inetmail")) {
712 flags |= US_INTERNET;
715 flags &= ~US_INTERNET ;
718 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
719 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
720 StrBuf_ServGetln(Buf);
721 if (GetServerStatus(Buf, NULL) == 2) {
722 FlushStrBuf(WCC->ImportantMsg);
723 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
726 username = bstr("newname");
730 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
741 StrBuf_ServGetln(Buf);
742 if (GetServerStatus(Buf, NULL) == 2) {
743 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
749 * If we are in the middle of creating a new user, move on to
750 * the vCard edit screen.
753 display_edit_address_book_entry(username, lbstr("usernum") );
756 select_user_to_edit(username);
762 * username the name of the user to remove
764 void delete_user(char *username) {
769 serv_printf("ASUP %s|0|0|0|0|0|", username);
770 StrBuf_ServGetln(Buf);
771 if (GetServerStatus(Buf, NULL) != 2)
772 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
774 select_user_to_edit( bstr("username"));
782 * take the web environment username and create it on the citadel server
784 void create_user(void) {
788 const char *username;
791 username = bstr("username");
792 serv_printf("CREU %s", username);
793 StrBuf_ServGetln(Buf);
794 if (GetServerStatus(Buf, &FullState) == 2) {
795 sprintf(WC->ImportantMessage, _("A new user has been created."));
796 display_edituser(username, 1);
798 else if (FullState == 570) {
799 StrBufPlain(WCC->ImportantMsg,
800 _("You are attempting to create a new user from within Citadel "
801 "while running in host based authentication mode. In this mode, "
802 "you must create new users on the host system, not within Citadel."),
804 select_user_to_edit(NULL);
807 StrBufAppendBuf(WCC->ImportantMsg, Buf, 4);
808 select_user_to_edit(NULL);
814 void _select_user_to_edit(void) {
815 select_user_to_edit(NULL);
819 void _display_edituser(void) {
820 display_edituser(NULL, 0);
823 void showuser(void) { do_template("user_show");}
830 WebcitAddUrlHandler(HKEY("showuser"), "", 0, showuser, 0);
831 WebcitAddUrlHandler(HKEY("select_user_to_edit"), "", 0, _select_user_to_edit, 0);
832 WebcitAddUrlHandler(HKEY("display_edituser"), "", 0, _display_edituser, 0);
833 WebcitAddUrlHandler(HKEY("edituser"), "", 0, edituser, 0);
834 WebcitAddUrlHandler(HKEY("create_user"), "", 0, create_user, 0);
836 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, NULL, CTX_USERLIST);
837 RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password, NULL, CTX_USERLIST);
838 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, NULL, CTX_USERLIST);
839 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, NULL, CTX_USERLIST);
840 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, NULL, CTX_USERLIST);
841 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, NULL, CTX_USERLIST);
842 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, NULL, CTX_USERLIST);
843 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, NULL, CTX_USERLIST);
844 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, NULL, CTX_USERLIST);
846 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, NULL, CTX_USERLIST);
847 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, NULL, CTX_USERLIST);
849 RegisterNamespace("USER:BIO", 1, 2, tmplput_USER_BIO, NULL, CTX_NONE);
851 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
852 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
853 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
854 RegisterConditional(HKEY("COND:USERLIST:HAVEBIO"), 0, ConditionalHaveBIO, CTX_USERLIST);
856 RegisterConditional(HKEY("COND:USER:PIC"), 1, Conditional_USER_HAS_PIC, CTX_NONE);
858 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_FLAG_DETECT_GROUPCHANGE);
862 RegisterSortFunc(HKEY("user:name"),
865 CompareUserListNameRev,
866 GroupchangeUserListName,
868 RegisterSortFunc(HKEY("user:accslvl"),
871 CompareAccessLevelRev,
872 GroupchangeAccessLevel,
875 RegisterSortFunc(HKEY("user:nlogons"),
882 RegisterSortFunc(HKEY("user:uid"),
889 RegisterSortFunc(HKEY("user:lastlogon"),
893 GroupchangeLastLogon,
896 RegisterSortFunc(HKEY("user:nmsgposts"),
903 REGISTERTokenParamDefine(AxDeleted);
904 REGISTERTokenParamDefine(AxNewU);
905 REGISTERTokenParamDefine(AxProbU);
906 REGISTERTokenParamDefine(AxLocU);
907 REGISTERTokenParamDefine(AxNetU);
908 REGISTERTokenParamDefine(AxPrefU);
909 REGISTERTokenParamDefine(AxAideU);