X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fuseredit.c;h=a6b4d4b44df152eb836e8acc4d06ee6a04e4cb2a;hb=c73091a2ae896b6be5aa94b911c1c89d76a85688;hp=c97a0a91ce50b6af9af038c906c037c5f28de024;hpb=e6b80ce244ae7d3b38d8fa2dd47ae095d19235d2;p=citadel.git diff --git a/webcit/useredit.c b/webcit/useredit.c index c97a0a91c..a6b4d4b44 100644 --- a/webcit/useredit.c +++ b/webcit/useredit.c @@ -1,103 +1,29 @@ /* - * $Id$ - */ -/** - * \defgroup AdminTasks Administrative screen to add/change/delete user accounts - * \ingroup CitadelConfig + * Copyright (c) 1996-2017 by the citadel.org team + * + * This program is open source software. You can redistribute it and/or + * modify it under the terms of the GNU General Public License, version 3. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ -/*@{*/ #include "webcit.h" #include "webserver.h" - -/** - * \brief show a list of available users to edit them - * \param message the header message??? - * \param preselect which user should be selected in the browser - */ -void select_user_to_edit(char *message, char *preselect) -{/* - char buf[SIZ]; - char username[SIZ]; +CtxType CTX_USERLIST = CTX_NONE; +/* + * show a list of available users to edit them + * message the header message??? + * preselect = which user should be selected in the browser */ +void select_user_to_edit(const char *preselect) +{ output_headers(1, 0, 0, 0, 1, 0); - do_template("edituser_select", NULL); + do_template("aide_edituser_select"); end_burst(); - -/* - - output_headers(1, 1, 2, 0, 0, 0); - wprintf("
\n"); - wprintf(""); - wprintf("

"); - wprintf(_("Edit or delete users")); - wprintf("

"); - wprintf("
"); - - wprintf("
\n"); - - if (message != NULL) wprintf(message); - - wprintf("
\n"); - - svput("BOXTITLE", WCS_STRING, _("Add users")); - do_template("beginbox", NULL); - - wprintf(_("To create a new user account, enter the desired " - "user name in the box below and click 'Create'.")); - wprintf("

"); - - wprintf("
\n"); - wprintf("\n", WC->nonce); - wprintf(_("New user: ")); - wprintf("
\n" - "" - "
\n", _("Create")); - - do_template("endbox", NULL); - - wprintf("
"); - - svput("BOXTITLE", WCS_STRING, _("Edit or Delete users")); - do_template("beginbox", NULL); - - wprintf(_("To edit an existing user account, select the user " - "name from the list and click 'Edit'.")); - wprintf("

"); - - wprintf("
" - "
\n"); - wprintf("\n", WC->nonce); - wprintf("
\n"); - - wprintf("", _("Edit configuration")); - wprintf("", _("Edit address book entry")); - wprintf("", _("Delete user"), _("Delete this user?")); - wprintf("
\n"); - do_template("endbox", NULL); - - wprintf("
\n"); - - wDumpContent(1); -*/ } @@ -109,15 +35,19 @@ typedef struct _UserListEntry { StrBuf *UserName; StrBuf *Passvoid; - StrBuf *LastLogon; time_t LastLogonT; /* Just available for Single users to view: */ unsigned int Flags; int DaysTillPurge; + int HasBio; + + StrBuf *PrimaryEmail; + StrBuf *OtherEmails; + } UserListEntry; -UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser) +UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser, const char *Pos) { UserListEntry *ul; @@ -126,33 +56,36 @@ UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser) ul = (UserListEntry*) malloc(sizeof(UserListEntry)); ul->UserName = NewStrBuf(); - ul->LastLogon = NewStrBuf(); ul->Passvoid = NewStrBuf(); - - StrBufExtract_token(ul->UserName, SerializedUser, 0, '|'); - StrBufExtract_token(ul->Passvoid, SerializedUser, 1, '|'); - ul->Flags = (unsigned int)StrBufExtract_long(SerializedUser, 2, '|'); - ul->nLogons = StrBufExtract_int(SerializedUser, 3, '|'); - ul->nPosts = StrBufExtract_int(SerializedUser, 4, '|'); - ul->AccessLevel = StrBufExtract_int(SerializedUser, 5, '|'); - ul->UID = StrBufExtract_int(SerializedUser, 6, '|'); - StrBufExtract_token(ul->LastLogon, SerializedUser, 7, '|'); - ul->LastLogonT = StrTol(ul->LastLogon); - ul->DaysTillPurge = StrBufExtract_int(SerializedUser, 8, '|'); + ul->PrimaryEmail = NewStrBuf(); + ul->OtherEmails = NewStrBuf(); + + StrBufExtract_NextToken(ul->UserName, SerializedUser, &Pos, '|'); + StrBufExtract_NextToken(ul->Passvoid, SerializedUser, &Pos, '|'); + ul->Flags = StrBufExtractNext_unsigned_long(SerializedUser, &Pos, '|'); + ul->nLogons = StrBufExtractNext_int( SerializedUser, &Pos, '|'); + ul->nPosts = StrBufExtractNext_int( SerializedUser, &Pos, '|'); + ul->AccessLevel = StrBufExtractNext_int( SerializedUser, &Pos, '|'); + ul->UID = StrBufExtractNext_int( SerializedUser, &Pos, '|'); + ul->LastLogonT = StrBufExtractNext_long( SerializedUser, &Pos, '|'); + ul->DaysTillPurge = StrBufExtractNext_int( SerializedUser, &Pos, '|'); return ul; } void DeleteUserListEntry(void *vUserList) { UserListEntry *ul = (UserListEntry*) vUserList; + if (!ul) return; FreeStrBuf(&ul->UserName); - FreeStrBuf(&ul->LastLogon); FreeStrBuf(&ul->Passvoid); + FreeStrBuf(&ul->PrimaryEmail); + FreeStrBuf(&ul->OtherEmails); free(ul); } UserListEntry* NewUserListEntry(StrBuf *SerializedUserList) { + const char *Pos = NULL; UserListEntry *ul; if (StrLength(SerializedUserList) < 8) @@ -160,18 +93,19 @@ UserListEntry* NewUserListEntry(StrBuf *SerializedUserList) ul = (UserListEntry*) malloc(sizeof(UserListEntry)); ul->UserName = NewStrBuf(); - ul->LastLogon = NewStrBuf(); ul->Passvoid = NewStrBuf(); - - StrBufExtract_token(ul->UserName, SerializedUserList, 0, '|'); - ul->AccessLevel = StrBufExtract_int(SerializedUserList, 1, '|'); - ul->UID = StrBufExtract_int(SerializedUserList, 2, '|'); - StrBufExtract_token(ul->LastLogon, SerializedUserList, 3, '|'); - /// TODO: ul->LastLogon -> ulLastLogonT - ul->nLogons = StrBufExtract_int(SerializedUserList, 4, '|'); - ul->nPosts = StrBufExtract_int(SerializedUserList, 5, '|'); - StrBufExtract_token(ul->Passvoid, SerializedUserList, 6, '|'); + ul->PrimaryEmail = NewStrBuf(); + ul->OtherEmails = NewStrBuf(); + + StrBufExtract_NextToken(ul->UserName, SerializedUserList, &Pos, '|'); + ul->AccessLevel = StrBufExtractNext_int( SerializedUserList, &Pos, '|'); + ul->UID = StrBufExtractNext_int( SerializedUserList, &Pos, '|'); + ul->LastLogonT = StrBufExtractNext_long(SerializedUserList, &Pos, '|'); + ul->nLogons = StrBufExtractNext_int( SerializedUserList, &Pos, '|'); + ul->nPosts = StrBufExtractNext_int( SerializedUserList, &Pos, '|'); + StrBufExtract_NextToken(ul->Passvoid, SerializedUserList, &Pos, '|'); ul->Flags = 0; + ul->HasBio = 0; ul->DaysTillPurge = -1; return ul; } @@ -181,53 +115,78 @@ UserListEntry* NewUserListEntry(StrBuf *SerializedUserList) */ int CompareUserListName(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName)); } + int CompareUserListNameRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName)); +} + +int GroupchangeUserListName(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName)); + return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0]; } /* - * Sort by AccessLevel + * Sort by access level */ int CompareAccessLevel(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->AccessLevel > u2->AccessLevel); } + int CompareAccessLevelRev(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u2->AccessLevel > u1->AccessLevel); } +int GroupchangeAccessLevel(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) vUser1; + UserListEntry *u2 = (UserListEntry*) vUser2; + + return u2->AccessLevel != u1->AccessLevel; +} /* * Sort by UID */ int CompareUID(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->UID > u2->UID); } + int CompareUIDRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->UID > u1->UID); +} + +int GroupchangeUID(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->UID > u1->UID); + return (u2->UID / 10) != (u1->UID / 10); } /* @@ -235,17 +194,26 @@ int CompareUIDRev(const void *vUser1, const void *vUser2) */ int CompareLastLogon(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->LastLogonT > u2->LastLogonT); } + int CompareLastLogonRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->LastLogonT > u1->LastLogonT); +} + +int GroupchangeLastLogon(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->LastLogonT > u1->LastLogonT); + return (u2->LastLogonT != u1->LastLogonT); } /* @@ -253,17 +221,26 @@ int CompareLastLogonRev(const void *vUser1, const void *vUser2) */ int ComparenLogons(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->nLogons > u2->nLogons); } + int ComparenLogonsRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->nLogons > u1->nLogons); +} + +int GroupchangenLogons(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->nLogons > u1->nLogons); + return (u2->nLogons / 100) != (u1->nLogons / 100); } /* @@ -271,162 +248,183 @@ int ComparenLogonsRev(const void *vUser1, const void *vUser2) */ int ComparenPosts(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->nPosts > u2->nPosts); } + int ComparenPostsRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->nPosts > u1->nPosts); +} + +int GroupchangenPosts(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->nPosts > u1->nPosts); + return (u2->nPosts / 100) != (u1->nPosts / 100); } -HashList *iterate_load_userlist(WCTemplateToken *Token) +HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP) { - HashList *Hash; - char buf[SIZ]; + int Done = 0; + CompareFunc SortIt; + HashList *Hash = NULL; StrBuf *Buf; UserListEntry* ul; - char nnn[64]; - int nUsed; - int Order; int len; - - serv_puts("LIST"); - serv_getln(buf, sizeof buf); - if (buf[0] == '1') { - Hash = NewHash(1, NULL); + int UID; + void *vData; + WCTemplputParams SubTP; - Buf = NewStrBuf(); - while ((len = StrBuf_ServGetln(Buf), - strcmp(ChrPtr(Buf), "000"))) { + memset(&SubTP, 0, sizeof(WCTemplputParams)); + serv_puts("LIST"); + Buf = NewStrBuf(); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 1) { + Hash = NewHash(1, Flathash); + Done = 0; + while (!Done) { + len = StrBuf_ServGetln(Buf); + if ((len <0) || + ((len == 3) && + !strcmp(ChrPtr(Buf), "000"))) + { + Done = 1; + break; + } ul = NewUserListEntry(Buf); if (ul == NULL) continue; - nUsed = GetCount(Hash); - nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1); - Put(Hash, nnn, nUsed, ul, DeleteUserListEntry); + + Put(Hash, IKEY(ul->UID), ul, DeleteUserListEntry); } - FreeStrBuf(&Buf); - Order = ibstr("SortOrder"); - switch (ibstr("SortBy")){ - case 1: /*NAME*/ - SortByPayload(Hash, (Order)? - CompareUserListName: - CompareUserListNameRev); - break; - case 2: /*AccessLevel*/ - SortByPayload(Hash, (Order)? - CompareAccessLevel: - CompareAccessLevelRev); - break; - case 3: /*nLogons*/ - SortByPayload(Hash, (Order)? - ComparenLogons: - ComparenLogonsRev); - break; - case 4: /*UID*/ - SortByPayload(Hash, (Order)? - CompareUID: - CompareUIDRev); - break; - case 5: /*LastLogon*/ - SortByPayload(Hash, (Order)? - CompareLastLogon: - CompareLastLogonRev); - break; - case 6: /* nLogons */ - SortByPayload(Hash, (Order)? - ComparenLogons: - ComparenLogonsRev); - break; - case 7: /* Posts */ - SortByPayload(Hash, (Order)? - ComparenPosts: - ComparenPostsRev); - break; + + serv_puts("LBIO 1"); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 1) { + Done = 0; + while (!Done) { + len = StrBuf_ServGetln(Buf); + if ((len <0) || ((len == 3) && !strcmp(ChrPtr(Buf), "000"))) + { + Done = 1; + break; + } + } + UID = atoi(ChrPtr(Buf)); + if (GetHash(Hash, IKEY(UID), &vData) && vData != 0) + { + ul = (UserListEntry*)vData; + ul->HasBio = 1; + } } - return Hash; + SubTP.Filter.ContextType = CTX_USERLIST; + SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0); + if (SortIt != NULL) + SortByPayload(Hash, SortIt); + else + SortByPayload(Hash, CompareUID); } - return NULL; + FreeStrBuf(&Buf); + return Hash; +} + + +void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP) +{ + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + StrBufAppendTemplate(Target, TP, ul->UserName, 0); +} + +void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP) +{ + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + StrBufAppendTemplate(Target, TP, ul->Passvoid, 0); } +void tmplput_USERLIST_PrimaryEmail(StrBuf *Target, WCTemplputParams *TP) +{ + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + StrBufAppendTemplate(Target, TP, ul->PrimaryEmail, 0); +} -void tmplput_USERLIST_UserName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_OtherEmails(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; -/// TODO: X - StrBufAppendBuf(Target, ul->UserName, 0); + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + StrBufAppendTemplate(Target, TP, ul->OtherEmails, 0); } -void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0); } -void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0); } -void tmplput_USERLIST_UID(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->UID, 0); } -void tmplput_USERLIST_LastLogonNo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); - StrBufAppendBuf(Target, ul->LastLogon, 0); + StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0); } -void tmplput_USERLIST_LastLogonStr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0); } -void tmplput_USERLIST_nLogons(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->nLogons, 0); } -void tmplput_USERLIST_nPosts(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->nPosts, 0); } -void tmplput_USERLIST_Flags(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->Flags, 0); } -void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) +void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0); } -int ConditionalUser(WCTemplateToken *Tokens, void *Context, int ContextType) +int ConditionalUser(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); if (havebstr("usernum")) { return ibstr("usernum") == ul->UID; } @@ -437,145 +435,236 @@ int ConditionalUser(WCTemplateToken *Tokens, void *Context, int ContextType) return 0; } -int ConditionalFlagINetEmail(WCTemplateToken *Tokens, void *Context, int ContextType) +int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); return (ul->Flags & US_INTERNET) != 0; } -int ConditionalUserAccess(WCTemplateToken *Tokens, void *Context, int ContextType) +int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP) { - UserListEntry *ul = (UserListEntry*) Context; + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + + if (ul == NULL) + return 0; - if (Tokens->Params[3]->Type == TYPE_LONG) - return (Tokens->Params[3]->lvalue == ul->AccessLevel); - else + return GetTemplateTokenNumber(Target, + TP, + 3, + AxNewU) + == + ul->AccessLevel; +} +int ConditionalHaveBIO(StrBuf *Target, WCTemplputParams *TP) +{ + UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST); + + if (ul == NULL) return 0; + return ul->HasBio; +} + +void tmplput_USER_BIO(StrBuf *Target, WCTemplputParams *TP) +{ + int Done = 0; + StrBuf *Buf; + const char *who; + long len; + + GetTemplateTokenString(Target, TP, 0, &who, &len); + if (len == 0) { + who = ChrPtr(WC->wc_fullname); + } + + Buf = NewStrBuf(); + serv_printf("RBIO %s", who); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 1) { + StrBuf *BioBuf = NewStrBufPlain(NULL, SIZ); + while (!Done && StrBuf_ServGetln(Buf)>=0) { + if ( (StrLength(Buf)==3) && + !strcmp(ChrPtr(Buf), "000")) + Done = 1; + else { + StrBufAppendBuf(BioBuf, Buf, 0); + StrBufAppendBufPlain(BioBuf, HKEY("\n"), 0); + } + } + StrBufAppendTemplate(Target, TP, BioBuf, 1); + FreeStrBuf(&BioBuf); + } + FreeStrBuf(&Buf); +} + + +int Conditional_USER_HAS_PIC(StrBuf *Target, WCTemplputParams *TP) +{ + // ajc 2016apr10 this needs to be re-evaluated with the new protocol + return(0); } -/** - * \brief Locate the message number of a user's vCard in the current room - * \param username the plaintext name of the user - * \param usernum the number of the user on the citadel server - * \return the message id of his vcard + +/* + * Locate the message number of a user's vCard in the current room + * Returns the message id of his vcard */ -long locate_user_vcard(char *username, long usernum) { - char buf[SIZ]; +long locate_user_vcard_in_this_room(message_summary **VCMsg, wc_mime_attachment **VCAtt) +{ + wcsession *WCC = WC; + HashPos *at; + HashPos *att; + const char *HashKey; + long HKLen; + void *vMsg; + message_summary *Msg; + wc_mime_attachment *Att; + StrBuf *Buf; long vcard_msgnum = (-1L); - char content_type[SIZ]; - char partnum[SIZ]; int already_tried_creating_one = 0; + StrBuf *FoundCharset = NewStrBuf(); + StrBuf *Error = NULL; + SharedMessageStatus Stat; - struct stuff_t { - struct stuff_t *next; - long msgnum; - }; - - struct stuff_t *stuff = NULL; - struct stuff_t *ptr; + Buf = NewStrBuf(); TRYAGAIN: - /** Search for the user's vCard */ - serv_puts("MSGS ALL"); - serv_getln(buf, sizeof buf); - if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - ptr = malloc(sizeof(struct stuff_t)); - ptr->msgnum = atol(buf); - ptr->next = stuff; - stuff = ptr; - } - - /** Iterate through the message list looking for vCards */ - while (stuff != NULL) { - serv_printf("MSG0 %ld|2", stuff->msgnum); - serv_getln(buf, sizeof buf); - if (buf[0]=='1') { - while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - if (!strncasecmp(buf, "part=", 5)) { - extract_token(partnum, &buf[5], 2, '|', sizeof partnum); - extract_token(content_type, &buf[5], 4, '|', sizeof content_type); - if ( (!strcasecmp(content_type, "text/x-vcard")) - || (!strcasecmp(content_type, "text/vcard")) ) { - vcard_msgnum = stuff->msgnum; + memset(&Stat, 0, sizeof(SharedMessageStatus)); + Stat.maxload = 10000; + Stat.lowest_found = (-1); + Stat.highest_found = (-1); + /* Search for the user's vCard */ + if (load_msg_ptrs("MSGS ALL||||1", NULL, NULL, &Stat, NULL, NULL, NULL, NULL, 0) > 0) { + at = GetNewHashPos(WCC->summ, 0); + while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) { + Msg = (message_summary*) vMsg; + Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment)); + memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment)); + Msg->MsgBody->msgnum = Msg->msgnum; + + load_message(Msg, FoundCharset, &Error); + + if (Msg->AllAttach != NULL) { + att = GetNewHashPos(Msg->AllAttach, 0); + while (GetNextHashPos(Msg->AllAttach, att, &HKLen, &HashKey, &vMsg) && + (vcard_msgnum == -1)) { + Att = (wc_mime_attachment*) vMsg; + if ( + (strcasecmp(ChrPtr(Att->ContentType), "text/x-vcard") == 0) + || (strcasecmp(ChrPtr(Att->ContentType), "text/vcard") == 0) + ) { + *VCAtt = Att; + *VCMsg = Msg; + vcard_msgnum = Msg->msgnum; + if (Att->Data == NULL) { + MimeLoadData(Att); + } } } + DeleteHashPos(&att); } + FreeStrBuf(&Error); /* don't care... */ + } - - ptr = stuff->next; - free(stuff); - stuff = ptr; + DeleteHashPos(&at); } - /** If there's no vcard, create one */ - if (vcard_msgnum < 0) if (already_tried_creating_one == 0) { + /* If there's no vcard, create one */ + if ((*VCMsg == NULL) && (already_tried_creating_one == 0)) { + FlushStrBuf(Buf); already_tried_creating_one = 1; serv_puts("ENT0 1|||4"); - serv_getln(buf, sizeof buf); - if (buf[0] == '4') { + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 4) { serv_puts("Content-type: text/x-vcard"); serv_puts(""); serv_puts("begin:vcard"); serv_puts("end:vcard"); serv_puts("000"); } + else + syslog(LOG_WARNING, "Error while creating user vcard: %s\n", ChrPtr(Buf)); goto TRYAGAIN; } + FreeStrBuf(&Buf); + FreeStrBuf(&FoundCharset); return(vcard_msgnum); } -/** - * \brief Display the form for editing a user's address book entry - * \param username the name of the user - * \param usernum the citadel-uid of the user +/* + * Display the form for editing a user's address book entry + * username the name of the user + * usernum the citadel-uid of the user */ -void display_edit_address_book_entry(char *username, long usernum) { - char roomname[SIZ]; - char buf[SIZ]; - char error_message[SIZ]; +void display_edit_address_book_entry(const char *username, long usernum) { + message_summary *VCMsg = NULL; + wc_mime_attachment *VCAtt = NULL; + StrBuf *roomname; + StrBuf *Buf; long vcard_msgnum = (-1L); - /** Locate the user's config room, creating it if necessary */ - sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM); - serv_printf("GOTO %s||1", roomname); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - serv_printf("CRE8 1|%s|5|||1|", roomname); - serv_getln(buf, sizeof buf); - serv_printf("GOTO %s||1", roomname); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - sprintf(error_message, - "" - "%s

\n", &buf[4]); - select_user_to_edit(error_message, username); + /* Locate the user's config room, creating it if necessary */ + Buf = NewStrBuf(); + roomname = NewStrBuf(); + StrBufPrintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM); + serv_printf("GOTO %s||1", ChrPtr(roomname)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) != 2) { + serv_printf("CRE8 1|%s|5|||1|", ChrPtr(roomname)); + StrBuf_ServGetln(Buf); + GetServerStatus(Buf, NULL); + serv_printf("GOTO %s||1", ChrPtr(roomname)); + StrBuf_ServGetln(Buf); + if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) { + select_user_to_edit(username); + FreeStrBuf(&Buf); + FreeStrBuf(&roomname); return; } } + FreeStrBuf(&Buf); - vcard_msgnum = locate_user_vcard(username, usernum); + locate_user_vcard_in_this_room(&VCMsg, &VCAtt); - if (vcard_msgnum < 0) { - sprintf(error_message, - "%s

\n", - _("An error occurred while trying to create or edit this address book entry.") - ); - select_user_to_edit(error_message, username); + if (VCMsg == NULL) { + AppendImportantMessage(_("An error occurred while trying to create or edit this address book entry."), -1); + select_user_to_edit(username); + FreeStrBuf(&roomname); return; } - do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname); + do_edit_vcard(vcard_msgnum, "1", + VCMsg, + VCAtt, + "select_user_to_edit", + ChrPtr(roomname)); + FreeStrBuf(&roomname); } +/* + * burge a user + * username the name of the user to remove + */ +void delete_user(char *username) { + StrBuf *Buf; + + Buf = NewStrBuf(); + serv_printf("ASUP %s|0|0|0|0|0|", username); + StrBuf_ServGetln(Buf); + GetServerStatusMsg(Buf, NULL, 1, 2); + + select_user_to_edit( bstr("username")); + FreeStrBuf(&Buf); +} + -void display_edituser(char *supplied_username, int is_new) { +void display_edituser(const char *supplied_username, int is_new) { + const char *Pos; UserListEntry* UL; StrBuf *Buf; - char error_message[1024]; - char MajorStatus; char username[256]; + int i = 0; if (supplied_username != NULL) { safestrncpy(username, supplied_username, sizeof username); @@ -587,231 +676,70 @@ void display_edituser(char *supplied_username, int is_new) { Buf = NewStrBuf(); serv_printf("AGUP %s", username); StrBuf_ServGetln(Buf); - MajorStatus = ChrPtr(Buf)[0]; - StrBufCutLeft(Buf, 4); - if (MajorStatus != '2') { - ///TODO ImportantMessage - sprintf(error_message, - "" - "%s

\n", ChrPtr(Buf)); - select_user_to_edit(error_message, username); + if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) { + select_user_to_edit(username); FreeStrBuf(&Buf); return; } else { - UL = NewUserListOneEntry(Buf); - output_headers(1, 0, 0, 0, 1, 0); - DoTemplate(HKEY("userlist_detailview"), NULL, (void*) UL, CTX_USERLIST); - end_burst(); - - } - FreeStrBuf(&Buf); -} - - - -/* * - * \brief Edit a user. - * If supplied_username is null, look in the "username" - * web variable for the name of the user to edit. - * - * If "is_new" is set to nonzero, this screen will set the web variables - * to send the user to the vCard editor next. - * \param supplied_username user to look up or NULL if to search in the environment - * \param is_new should we create the user? - * / -void display_edituser(char *supplied_username, int is_new) { - char buf[1024]; - char error_message[1024]; - time_t now; - - char username[256]; - char password[256]; - unsigned int flags; - int timescalled; - int msgsposted; - int axlevel; - long usernum; - time_t lastcall; - int purgedays; - int i; - - if (supplied_username != NULL) { - safestrncpy(username, supplied_username, sizeof username); - } - else { - safestrncpy(username, bstr("username"), sizeof username); - } - - serv_printf("AGUP %s", username); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - sprintf(error_message, - "" - "%s

\n", &buf[4]); - select_user_to_edit(error_message, username); - return; - } - - extract_token(username, &buf[4], 0, '|', sizeof username); - extract_token(password, &buf[4], 1, '|', sizeof password); - flags = extract_int(&buf[4], 2); - timescalled = extract_int(&buf[4], 3); - msgsposted = extract_int(&buf[4], 4); - axlevel = extract_int(&buf[4], 5); - usernum = extract_long(&buf[4], 6); - lastcall = extract_long(&buf[4], 7); - purgedays = extract_long(&buf[4], 8); - - if (havebstr("edit_abe_button")) { - display_edit_address_book_entry(username, usernum); - return; - } - - if (havebstr("delete_button")) { - delete_user(username); - return; - } + Pos = ChrPtr(Buf) + 4; + UL = NewUserListOneEntry(Buf, Pos); + if ((UL != NULL) && havebstr("edit_abe_button")) { + display_edit_address_book_entry(username, UL->UID); + } + else if ((UL != NULL) && havebstr("delete_button")) { + delete_user(username); + } + else if (UL != NULL) { + + serv_printf("AGEA %s", username); + StrBuf_ServGetln(Buf); + if (GetServerStatusMsg(Buf, NULL, 1, 2) == 1) { + while(StrBuf_ServGetln(Buf) , strcmp(ChrPtr(Buf), "000")) { + if (i == 0) { + StrBufAppendPrintf(UL->PrimaryEmail, "%s", ChrPtr(Buf)); + } + if (i > 1) { + StrBufAppendPrintf(UL->OtherEmails, ","); + } + if (i > 0) { + StrBufAppendPrintf(UL->OtherEmails, "%s", ChrPtr(Buf)); + } + ++i; + } + } - output_headers(1, 1, 2, 0, 0, 0); - wprintf("
\n"); - wprintf("

"); - wprintf(_("Edit user account: ")); - escputs(username); - wprintf("

"); - wprintf("
"); - - wprintf("
\n"); - - wprintf("
" - "
\n"); - wprintf("
\n" - "\n"); - wprintf("\n" - "\n", - is_new, usernum); - wprintf("\n", WC->nonce); - - wprintf("\n", flags); - - wprintf("
"); - - wprintf("\n"); - - wprintf("\n"); - - wprintf("\n"); - - wprintf("\n"); - - wprintf("\n"); - - wprintf("\n"); - - wprintf("\n"); - - now = time(NULL); - wprintf(""); - - wprintf("\n"); - - wprintf("
"); - wprintf(_("User name:")); - wprintf("" - "
"); - wprintf(_("Password")); - wprintf("" - "
"); - wprintf(_("Permission to send Internet mail")); - wprintf(""); - wprintf("
"); - wprintf(_("Number of logins")); - wprintf("" - "
"); - wprintf(_("Messages submitted")); - wprintf("" - "
"); - wprintf(_("Access level")); - wprintf("" - "
"); - wprintf(_("User ID number")); - wprintf("" - "
"); - wprintf(_("Date and time of last login")); - wprintf("" - "
"); - wprintf(_("Auto-purge after this many days")); - wprintf("" - "
\n"); - - wprintf("\n" - " " - "\n" - "

\n", _("Save changes"), _("Cancel")); - - wprintf("
\n"); - wprintf("
\n"); - wDumpContent(1); - + FreeStrBuf(&Buf); } -*/ -/** - * \brief do the backend operation of the user edit on the server +/* + * do the backend operation of the user edit on the server */ void edituser(void) { - char message[SIZ]; - char buf[SIZ]; int is_new = 0; unsigned int flags = 0; - char *username; + const char *username; is_new = ibstr("is_new"); - safestrncpy(message, "", sizeof message); username = bstr("username"); if (!havebstr("ok_button")) { - safestrncpy(message, _("Changes were not saved."), sizeof message); - } - + AppendImportantMessage(_("Changes were not saved."), -1); + } else { + StrBuf *Buf = NewStrBuf(); + flags = ibstr("flags"); if (yesbstr("inetmail")) { flags |= US_INTERNET; @@ -822,17 +750,13 @@ void edituser(void) { if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) { serv_printf("RENU %s|%s", bstr("username"), bstr("newname")); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - sprintf(&message[strlen(message)], - "" - "%s

\n", &buf[4]); - } - else { + StrBuf_ServGetln(Buf); + if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) { username = bstr("newname"); } } + /* Send the new account parameters */ serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|", username, bstr("password"), @@ -844,15 +768,42 @@ void edituser(void) { bstr("lastcall"), bstr("purgedays") ); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - sprintf(&message[strlen(message)], - "" - "%s

\n", &buf[4]); + StrBuf_ServGetln(Buf); + GetServerStatusMsg(Buf, NULL, 1, 2); + + /* Send the new email addresses. First make up a delimited list... */ + char all_the_emails[512]; + snprintf(all_the_emails, sizeof all_the_emails, "%s,%s", bstr("primaryemail"), bstr("otheremails")); + + /* Replace any commas, semicolons, or spaces with newlines */ + char *pos; + for (pos=all_the_emails; *pos!=0; ++pos) { + if ((*pos == ',') || (*pos == ';') || (*pos == ' ')) *pos = '\n' ; + } + + /* Remove any naughty inappropriate whitespace */ + striplt(all_the_emails); + while (pos = strstr(all_the_emails, "\n,"), (pos != NULL)) { + strcpy(pos, pos+1); + } + while (pos = strstr(all_the_emails, ",\n"), (pos != NULL)) { + strcpy(pos+1, pos+2); + } + while (pos = strstr(all_the_emails, "\n\n"), (pos != NULL)) { + strcpy(pos+1, pos+2); } + + /* Now send it to the server. */ + serv_printf("ASEA %s", username); + StrBuf_ServGetln(Buf); + if (GetServerStatusMsg(Buf, NULL, 1, 2) == 4) { + serv_printf("%s\n000", all_the_emails); + } + + FreeStrBuf(&Buf); } - /** + /* * If we are in the middle of creating a new user, move on to * the vCard edit screen. */ @@ -860,99 +811,161 @@ void edituser(void) { display_edit_address_book_entry(username, lbstr("usernum") ); } else { - select_user_to_edit(message, username); + select_user_to_edit(username); } } -/* - * \brief burge a user - * \param username the name of the user to remove - */ -void delete_user(char *username) { - char buf[SIZ]; - char message[SIZ]; - - serv_printf("ASUP %s|0|0|0|0|0|", username); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - sprintf(message, - "" - "%s

\n", &buf[4]); - } - else { - safestrncpy(message, "", sizeof message); - } - select_user_to_edit(message, bstr("username")); -} - -/** - * \brief create a new user +/* + * create a new user * take the web environment username and create it on the citadel server */ void create_user(void) { - char buf[SIZ]; - char error_message[SIZ]; - char username[SIZ]; - - safestrncpy(username, bstr("username"), sizeof username); + long FullState; + StrBuf *Buf; + const char *username; + Buf = NewStrBuf(); + username = bstr("username"); serv_printf("CREU %s", username); - serv_getln(buf, sizeof buf); - - if (buf[0] == '2') { - sprintf(WC->ImportantMessage, _("A new user has been created.")); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, &FullState) == 2) { + AppendImportantMessage(_("A new user has been created."), -1); display_edituser(username, 1); } - else if (!strncmp(buf, "570", 3)) { - sprintf(error_message, - "" - "%s

\n", - _("You are attempting to create a new user from within Citadel " - "while running in host based authentication mode. In this mode, " - "you must create new users on the host system, not within Citadel.") - ); - select_user_to_edit(error_message, NULL); + else if (FullState == 570) { + AppendImportantMessage(_("You are attempting to create a new user from within Citadel " + "while running in host based authentication mode. In this mode, " + "you must create new users on the host system, not within Citadel."), + -1); + select_user_to_edit(NULL); } else { - sprintf(error_message, - "" - "%s

\n", &buf[4]); - select_user_to_edit(error_message, NULL); + AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4); + select_user_to_edit(NULL); } + FreeStrBuf(&Buf); +} + +void display_userpic(void) { + off_t bytes; + StrBuf *Buf = NewStrBuf(); + const char *username = bstr("user"); + serv_printf("DLUI %s", username); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 6) { + StrBufCutLeft(Buf, 4); + bytes = StrBufExtract_long(Buf, 0, '|'); + StrBuf *content_type = NewStrBuf(); + StrBufExtract_token(content_type, Buf, 3, '|'); + WC->WBuf = NewStrBuf(); + StrBuf_ServGetBLOBBuffered(WC->WBuf, bytes); + http_transmit_thing(ChrPtr(content_type), 0); + FreeStrBuf(&content_type); + } + else { + output_error_pic("", ""); + } + FreeStrBuf(&Buf); } -void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);} -void _display_edituser(void) {display_edituser(NULL, 0);} +void _select_user_to_edit(void) { + select_user_to_edit(NULL); +} + + +void _display_edituser(void) { + display_edituser(NULL, 0); +} void InitModule_USEREDIT (void) { - WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0); - WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0); - WebcitAddUrlHandler(HKEY("edituser"), edituser, 0); - WebcitAddUrlHandler(HKEY("create_user"), create_user, 0); - - RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST); - RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST); - RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST); - RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST); - RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST); - RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST); - RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST); - RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST); - - RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST); - RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST); - - RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST); - RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST); - RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST); - - RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST); -} -/*@}*/ + RegisterCTX(CTX_USERLIST); + WebcitAddUrlHandler(HKEY("select_user_to_edit"), "", 0, _select_user_to_edit, 0); + WebcitAddUrlHandler(HKEY("display_edituser"), "", 0, _display_edituser, 0); + WebcitAddUrlHandler(HKEY("edituser"), "", 0, edituser, 0); + WebcitAddUrlHandler(HKEY("create_user"), "", 0, create_user, 0); + WebcitAddUrlHandler(HKEY("userpic"), "", 0, display_userpic, 0); + + RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:PRIMARYEMAIL", 0, 1, tmplput_USERLIST_PrimaryEmail, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:OTHEREMAILS", 0, 1, tmplput_USERLIST_OtherEmails, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, NULL, CTX_USERLIST); + RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, NULL, CTX_USERLIST); + + RegisterNamespace("USER:BIO", 1, 2, tmplput_USER_BIO, NULL, CTX_NONE); + + RegisterConditional("COND:USERNAME", 0, ConditionalUser, CTX_USERLIST); + RegisterConditional("COND:USERACCESS", 0, ConditionalUserAccess, CTX_USERLIST); + RegisterConditional("COND:USERLIST:FLAG:USE_INTERNET", 0, ConditionalFlagINetEmail, CTX_USERLIST); + RegisterConditional("COND:USERLIST:HAVEBIO", 0, ConditionalHaveBIO, CTX_USERLIST); + + RegisterConditional("COND:USER:PIC", 1, Conditional_USER_HAS_PIC, CTX_NONE); + + RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_FLAG_DETECT_GROUPCHANGE); + + + + RegisterSortFunc(HKEY("user:name"), + HKEY("userlist"), + CompareUserListName, + CompareUserListNameRev, + GroupchangeUserListName, + CTX_USERLIST); + RegisterSortFunc(HKEY("user:accslvl"), + HKEY("userlist"), + CompareAccessLevel, + CompareAccessLevelRev, + GroupchangeAccessLevel, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:nlogons"), + HKEY("userlist"), + ComparenLogons, + ComparenLogonsRev, + GroupchangenLogons, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:uid"), + HKEY("userlist"), + CompareUID, + CompareUIDRev, + GroupchangeUID, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:lastlogon"), + HKEY("userlist"), + CompareLastLogon, + CompareLastLogonRev, + GroupchangeLastLogon, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:nmsgposts"), + HKEY("userlist"), + ComparenPosts, + ComparenPostsRev, + GroupchangenPosts, + CTX_USERLIST); + + REGISTERTokenParamDefine(AxDeleted); + REGISTERTokenParamDefine(AxNewU); + REGISTERTokenParamDefine(AxProbU); + REGISTERTokenParamDefine(AxLocU); + REGISTERTokenParamDefine(AxNetU); + REGISTERTokenParamDefine(AxPrefU); + REGISTERTokenParamDefine(AxAideU); +} +