Back to index

webcit  8.12-dfsg
useredit.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1996-2012 by the citadel.org team
00003  *
00004  * This program is open source software.  You can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License, version 3.
00006  *
00007  * This program is distributed in the hope that it will be useful,
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  * GNU General Public License for more details.
00011  */
00012 
00013 #include "webcit.h"
00014 #include "webserver.h"
00015 
00016 
00017 /*
00018  *  show a list of available users to edit them
00019  *  message the header message???
00020  *  preselect = which user should be selected in the browser
00021  */
00022 void select_user_to_edit(const char *preselect)
00023 {
00024        output_headers(1, 0, 0, 0, 1, 0);
00025        do_template("aide_edituser_select");
00026         end_burst();
00027 }
00028 
00029 
00030 typedef struct _UserListEntry {
00031        int UID;
00032        int AccessLevel;
00033        int nLogons;
00034        int nPosts;
00035 
00036        StrBuf *UserName;
00037        StrBuf *Passvoid;
00038        time_t LastLogonT;
00039        /* Just available for Single users to view: */
00040        unsigned int Flags;
00041        int DaysTillPurge;
00042        int HasBio;
00043 } UserListEntry;
00044 
00045 
00046 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser, const char *Pos)
00047 {
00048        UserListEntry *ul;
00049 
00050        if (StrLength(SerializedUser) < 8) 
00051               return NULL;
00052 
00053        ul = (UserListEntry*) malloc(sizeof(UserListEntry));
00054        ul->UserName = NewStrBuf();
00055        ul->Passvoid = NewStrBuf();
00056 
00057        StrBufExtract_NextToken(ul->UserName,               SerializedUser, &Pos, '|');
00058        StrBufExtract_NextToken(ul->Passvoid,               SerializedUser, &Pos, '|');
00059        ul->Flags         = StrBufExtractNext_unsigned_long(SerializedUser, &Pos, '|');
00060        ul->nLogons       = StrBufExtractNext_int(          SerializedUser, &Pos, '|');
00061        ul->nPosts        = StrBufExtractNext_int(          SerializedUser, &Pos, '|');
00062        ul->AccessLevel   = StrBufExtractNext_int(          SerializedUser, &Pos, '|');
00063        ul->UID           = StrBufExtractNext_int(          SerializedUser, &Pos, '|');
00064        ul->LastLogonT    = StrBufExtractNext_long(         SerializedUser, &Pos, '|');
00065        ul->DaysTillPurge = StrBufExtractNext_int(          SerializedUser, &Pos, '|');
00066        return ul;
00067 }
00068 
00069 void DeleteUserListEntry(void *vUserList)
00070 {
00071        UserListEntry *ul = (UserListEntry*) vUserList;
00072        if (!ul) return;
00073        FreeStrBuf(&ul->UserName);
00074        FreeStrBuf(&ul->Passvoid);
00075        free(ul);
00076 }
00077 
00078 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
00079 {
00080        const char *Pos = NULL;
00081        UserListEntry *ul;
00082 
00083        if (StrLength(SerializedUserList) < 8) 
00084               return NULL;
00085 
00086        ul = (UserListEntry*) malloc(sizeof(UserListEntry));
00087        ul->UserName = NewStrBuf();
00088        ul->Passvoid = NewStrBuf();
00089 
00090        StrBufExtract_NextToken(ul->UserName,    SerializedUserList, &Pos, '|');
00091        ul->AccessLevel = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
00092        ul->UID         = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
00093        ul->LastLogonT  = StrBufExtractNext_long(SerializedUserList, &Pos, '|');
00094        ul->nLogons     = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
00095        ul->nPosts      = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
00096        StrBufExtract_NextToken(ul->Passvoid,    SerializedUserList, &Pos, '|');
00097        ul->Flags = 0;
00098        ul->HasBio = 0;
00099        ul->DaysTillPurge = -1;
00100        return ul;
00101 }
00102 
00103 /*
00104  * Sort by Username
00105  */
00106 int CompareUserListName(const void *vUser1, const void *vUser2)
00107 {
00108        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00109        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00110 
00111        return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
00112 }
00113 
00114 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
00115 {
00116        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00117        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00118        return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
00119 }
00120 
00121 int GroupchangeUserListName(const void *vUser1, const void *vUser2)
00122 {
00123        UserListEntry *u1 = (UserListEntry*) vUser1;
00124        UserListEntry *u2 = (UserListEntry*) vUser2;
00125        return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0];
00126 }
00127 
00128 /*
00129  * Sort by access level
00130  */
00131 int CompareAccessLevel(const void *vUser1, const void *vUser2)
00132 {
00133        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00134        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00135 
00136        return (u1->AccessLevel > u2->AccessLevel);
00137 }
00138 
00139 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
00140 {
00141        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00142        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00143 
00144        return (u2->AccessLevel > u1->AccessLevel);
00145 }
00146 
00147 int GroupchangeAccessLevel(const void *vUser1, const void *vUser2)
00148 {
00149        UserListEntry *u1 = (UserListEntry*) vUser1;
00150        UserListEntry *u2 = (UserListEntry*) vUser2;
00151 
00152        return u2->AccessLevel != u1->AccessLevel;
00153 }
00154 
00155 /*
00156  * Sort by UID
00157  */
00158 int CompareUID(const void *vUser1, const void *vUser2)
00159 {
00160        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00161        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00162 
00163        return (u1->UID > u2->UID);
00164 }
00165 
00166 int CompareUIDRev(const void *vUser1, const void *vUser2)
00167 {
00168        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00169        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00170 
00171        return (u2->UID > u1->UID);
00172 }
00173 
00174 int GroupchangeUID(const void *vUser1, const void *vUser2)
00175 {
00176        UserListEntry *u1 = (UserListEntry*) vUser1;
00177        UserListEntry *u2 = (UserListEntry*) vUser2;
00178 
00179        return (u2->UID / 10) != (u1->UID / 10);
00180 }
00181 
00182 /*
00183  * Sort By Date /// TODO!
00184  */
00185 int CompareLastLogon(const void *vUser1, const void *vUser2)
00186 {
00187        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00188        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00189 
00190        return (u1->LastLogonT > u2->LastLogonT);
00191 }
00192 
00193 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
00194 {
00195        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00196        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00197 
00198        return (u2->LastLogonT > u1->LastLogonT);
00199 }
00200 
00201 int GroupchangeLastLogon(const void *vUser1, const void *vUser2)
00202 {
00203        UserListEntry *u1 = (UserListEntry*) vUser1;
00204        UserListEntry *u2 = (UserListEntry*) vUser2;
00205 
00206        return (u2->LastLogonT != u1->LastLogonT);
00207 }
00208 
00209 /*
00210  * Sort By Number of Logons
00211  */
00212 int ComparenLogons(const void *vUser1, const void *vUser2)
00213 {
00214        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00215        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00216 
00217        return (u1->nLogons > u2->nLogons);
00218 }
00219 
00220 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
00221 {
00222        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00223        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00224 
00225        return (u2->nLogons > u1->nLogons);
00226 }
00227 
00228 int GroupchangenLogons(const void *vUser1, const void *vUser2)
00229 {
00230        UserListEntry *u1 = (UserListEntry*) vUser1;
00231        UserListEntry *u2 = (UserListEntry*) vUser2;
00232 
00233        return (u2->nLogons / 100) != (u1->nLogons / 100);
00234 }
00235 
00236 /*
00237  * Sort By Number of Posts
00238  */
00239 int ComparenPosts(const void *vUser1, const void *vUser2)
00240 {
00241        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00242        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00243 
00244        return (u1->nPosts > u2->nPosts);
00245 }
00246 
00247 int ComparenPostsRev(const void *vUser1, const void *vUser2)
00248 {
00249        UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
00250        UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
00251 
00252        return (u2->nPosts > u1->nPosts);
00253 }
00254 
00255 int GroupchangenPosts(const void *vUser1, const void *vUser2)
00256 {
00257        UserListEntry *u1 = (UserListEntry*) vUser1;
00258        UserListEntry *u2 = (UserListEntry*) vUser2;
00259 
00260        return (u2->nPosts / 100) != (u1->nPosts / 100);
00261 }
00262 
00263 
00264 HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP)
00265 {
00266        int Done = 0;
00267        CompareFunc SortIt;
00268        HashList *Hash = NULL;
00269        StrBuf *Buf;
00270        UserListEntry* ul;
00271        int len;
00272        int UID;
00273        void *vData;
00274        WCTemplputParams SubTP;
00275 
00276        memset(&SubTP, 0, sizeof(WCTemplputParams));     
00277         serv_puts("LIST");
00278        Buf = NewStrBuf();
00279        StrBuf_ServGetln(Buf);
00280        if (GetServerStatus(Buf, NULL) == 1) {
00281               Hash = NewHash(1, Flathash);
00282 
00283               while (!Done) {
00284                      len = StrBuf_ServGetln(Buf);
00285                      if ((len <0) || 
00286                          ((len == 3) &&
00287                           !strcmp(ChrPtr(Buf), "000")))
00288                      {
00289                             Done = 1;
00290                             break;
00291                      }
00292                      ul = NewUserListEntry(Buf);
00293                      if (ul == NULL)
00294                             continue;
00295 
00296                      Put(Hash, IKEY(ul->UID), ul, DeleteUserListEntry); 
00297               }
00298 
00299               serv_puts("LBIO 1");
00300               StrBuf_ServGetln(Buf);
00301               if (GetServerStatus(Buf, NULL) == 1)
00302                      Done = 0;
00303                      while (!Done) {
00304                      len = StrBuf_ServGetln(Buf);
00305                      if ((len <0) || 
00306                          ((len == 3) &&
00307                           !strcmp(ChrPtr(Buf), "000")))
00308                      {
00309                             Done = 1;
00310                             break;
00311                      }
00312                      UID = atoi(ChrPtr(Buf));
00313                      if (GetHash(Hash, IKEY(UID), &vData) && vData != 0)
00314                      {
00315                             ul = (UserListEntry*)vData;
00316                             ul->HasBio = 1;
00317                      }
00318               }
00319               SubTP.Filter.ContextType = CTX_USERLIST;
00320               SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0);
00321               if (SortIt != NULL)
00322                      SortByPayload(Hash, SortIt);
00323               else 
00324                      SortByPayload(Hash, CompareUID);
00325         }
00326        FreeStrBuf(&Buf);
00327        return Hash;
00328 }
00329 
00330 
00331 void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP)
00332 {
00333        UserListEntry *ul = (UserListEntry*) CTX;
00334        StrBufAppendTemplate(Target, TP, ul->UserName, 0);
00335 }
00336 
00337 void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP)
00338 {
00339        UserListEntry *ul = (UserListEntry*) CTX;
00340        StrBufAppendTemplate(Target, TP, ul->Passvoid, 0);
00341 }
00342 
00343 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
00344 {
00345        UserListEntry *ul = (UserListEntry*) CTX;
00346 
00347        StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
00348 }
00349 
00350 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
00351 {
00352        UserListEntry *ul = (UserListEntry*) CTX;
00353        
00354        StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
00355 }
00356 
00357 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
00358 {
00359        UserListEntry *ul = (UserListEntry*) CTX;
00360 
00361        StrBufAppendPrintf(Target, "%d", ul->UID, 0);
00362 }
00363 
00364 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
00365 {
00366        UserListEntry *ul = (UserListEntry*) CTX;
00367 
00368        StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
00369 }
00370 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
00371 {
00372        UserListEntry *ul = (UserListEntry*) CTX;
00373        StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
00374 }
00375 
00376 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
00377 {
00378        UserListEntry *ul = (UserListEntry*) CTX;
00379 
00380        StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
00381 }
00382 
00383 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
00384 {
00385        UserListEntry *ul = (UserListEntry*) CTX;
00386 
00387        StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
00388 }
00389 
00390 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
00391 {
00392        UserListEntry *ul = (UserListEntry*) CTX;
00393 
00394        StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
00395 }
00396 
00397 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
00398 {
00399        UserListEntry *ul = (UserListEntry*) CTX;
00400 
00401        StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
00402 }
00403 
00404 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
00405 {
00406        UserListEntry *ul = (UserListEntry*) CTX;
00407        if (havebstr("usernum")) {
00408               return ibstr("usernum") == ul->UID;
00409        }
00410        else if (havebstr("username")) {
00411               return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
00412        }
00413        else 
00414               return 0;
00415 }
00416 
00417 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
00418 {
00419        UserListEntry *ul = (UserListEntry*) CTX;
00420        return (ul->Flags & US_INTERNET) != 0;
00421 }
00422 
00423 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
00424 {
00425        UserListEntry *ul = (UserListEntry*) CTX;
00426        
00427        if (ul == NULL)
00428               return 0;
00429 
00430        return GetTemplateTokenNumber(Target, 
00431                                   TP, 
00432                                   3, 
00433                                   AxNewU)
00434               ==
00435               ul->AccessLevel;
00436 }
00437 int ConditionalHaveBIO(StrBuf *Target, WCTemplputParams *TP)
00438 {
00439        UserListEntry *ul = (UserListEntry*) CTX;
00440        
00441        if (ul == NULL)
00442               return 0;
00443        return ul->HasBio;
00444 }
00445 
00446 void tmplput_USER_BIO(StrBuf *Target, WCTemplputParams *TP)
00447 {
00448        int Done = 0;
00449        StrBuf *Buf;
00450        const char *who;
00451        long len;
00452 
00453        GetTemplateTokenString(Target, TP, 0, &who, &len);
00454 
00455        Buf = NewStrBuf();
00456        serv_printf("RBIO %s", who);
00457        StrBuf_ServGetln(Buf);
00458        if (GetServerStatus(Buf, NULL) == 1) {
00459               StrBuf *BioBuf = NewStrBufPlain(NULL, SIZ);
00460               while (!Done && StrBuf_ServGetln(Buf)>=0) {
00461                      if ( (StrLength(Buf)==3) && 
00462                           !strcmp(ChrPtr(Buf), "000")) 
00463                             Done = 1;
00464                      else
00465                             StrBufAppendBuf(BioBuf, Buf, 0);
00466               }
00467               StrBufAppendTemplate(Target, TP, BioBuf, 1);
00468               FreeStrBuf(&BioBuf);
00469        }
00470        FreeStrBuf(&Buf);
00471 }
00472 
00473 int Conditional_USER_HAS_PIC(StrBuf *Target, WCTemplputParams *TP)
00474 {
00475        StrBuf *Buf;
00476        const char *who;
00477        long len;
00478        int r = 0;
00479 
00480        GetTemplateTokenString(Target, TP, 2, &who, &len);
00481 
00482        Buf = NewStrBuf();
00483        serv_printf("OIMG _userpic_|%s", who);
00484        StrBuf_ServGetln(Buf);
00485        if (GetServerStatus(Buf, NULL) != 2) {
00486               r = 1;
00487        }
00488        else {
00489               r = 0;
00490        }
00491        serv_puts("CLOS");
00492        StrBuf_ServGetln(Buf);
00493        GetServerStatus(Buf, NULL);
00494        FreeStrBuf(&Buf);
00495        return(r);
00496 }
00497 
00498 
00499 /*
00500  *  Locate the message number of a user's vCard in the current room
00501  *  Returns the message id of his vcard
00502  */
00503 long locate_user_vcard_in_this_room(message_summary **VCMsg, wc_mime_attachment **VCAtt)
00504 {
00505        wcsession *WCC = WC;
00506        HashPos *at;
00507        HashPos *att;
00508        const char *HashKey;
00509        long HKLen;
00510        void *vMsg;
00511        message_summary *Msg;
00512        wc_mime_attachment *Att;
00513        StrBuf *Buf;
00514        long vcard_msgnum = (-1L);
00515        int already_tried_creating_one = 0;
00516        StrBuf *FoundCharset = NewStrBuf();
00517        StrBuf *Error = NULL;
00518        SharedMessageStatus Stat;
00519 
00520 
00521        Buf = NewStrBuf();
00522 TRYAGAIN:
00523        memset(&Stat, 0, sizeof(SharedMessageStatus));
00524        Stat.maxload = 10000;
00525        Stat.lowest_found = (-1);
00526        Stat.highest_found = (-1);
00527        /* Search for the user's vCard */
00528        if (load_msg_ptrs("MSGS ALL||||1", NULL, &Stat, NULL) > 0) {
00529               at = GetNewHashPos(WCC->summ, 0);
00530               while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
00531                      Msg = (message_summary*) vMsg;            
00532                      Msg->MsgBody =  (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
00533                      memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment));
00534                      Msg->MsgBody->msgnum = Msg->msgnum;
00535 
00536                      load_message(Msg, FoundCharset, &Error);
00537                      
00538                      if (Msg->AllAttach != NULL) {
00539                             att = GetNewHashPos(Msg->AllAttach, 0);
00540                             while (GetNextHashPos(Msg->AllAttach, att, &HKLen, &HashKey, &vMsg) && 
00541                                    (vcard_msgnum == -1)) {
00542                                    Att = (wc_mime_attachment*) vMsg;
00543                                    if (
00544                                           (strcasecmp(ChrPtr(Att->ContentType), "text/x-vcard") == 0)
00545                                           || (strcasecmp(ChrPtr(Att->ContentType), "text/vcard") == 0)
00546                                    ) {
00547                                           *VCAtt = Att;
00548                                           *VCMsg = Msg;
00549                                           vcard_msgnum = Msg->msgnum;
00550                                           if (Att->Data == NULL) {
00551                                                  MimeLoadData(Att);
00552                                           }
00553                                    }
00554                             }
00555                             DeleteHashPos(&att);
00556                      }
00557                      FreeStrBuf(&Error);  /* don't care... */
00558                      
00559               }
00560               DeleteHashPos(&at);         
00561        }
00562 
00563        /* If there's no vcard, create one */
00564        if ((*VCMsg == NULL) && (already_tried_creating_one == 0)) {
00565               FlushStrBuf(Buf);
00566               already_tried_creating_one = 1;
00567               serv_puts("ENT0 1|||4");
00568               StrBuf_ServGetln(Buf);
00569               if (GetServerStatus(Buf, NULL) == 4) {
00570                      serv_puts("Content-type: text/x-vcard");
00571                      serv_puts("");
00572                      serv_puts("begin:vcard");
00573                      serv_puts("end:vcard");
00574                      serv_puts("000");
00575               }
00576               else 
00577                      syslog(1, "Error while creating user vcard: %s\n", ChrPtr(Buf));
00578               goto TRYAGAIN;
00579        }
00580        FreeStrBuf(&Buf);
00581        FreeStrBuf(&FoundCharset);
00582 
00583        return(vcard_msgnum);
00584 }
00585 
00586 
00587 /*
00588  *  Display the form for editing a user's address book entry
00589  *  username the name of the user
00590  *  usernum the citadel-uid of the user
00591  */
00592 void display_edit_address_book_entry(const char *username, long usernum) {
00593        message_summary *VCMsg = NULL;
00594        wc_mime_attachment *VCAtt = NULL;
00595        StrBuf *roomname;
00596        StrBuf *Buf;
00597        long vcard_msgnum = (-1L);
00598 
00599        /* Locate the user's config room, creating it if necessary */
00600        Buf = NewStrBuf();
00601        roomname = NewStrBuf();
00602        StrBufPrintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
00603        serv_printf("GOTO %s||1", ChrPtr(roomname));
00604        StrBuf_ServGetln(Buf);
00605        if (GetServerStatus(Buf, NULL) != 2) {
00606               serv_printf("CRE8 1|%s|5|||1|", ChrPtr(roomname));
00607               StrBuf_ServGetln(Buf);
00608               GetServerStatus(Buf, NULL);
00609               serv_printf("GOTO %s||1", ChrPtr(roomname));
00610               StrBuf_ServGetln(Buf);
00611               if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
00612                      select_user_to_edit(username);
00613                      FreeStrBuf(&Buf);
00614                      FreeStrBuf(&roomname);
00615                      return;
00616               }
00617        }
00618        FreeStrBuf(&Buf);
00619 
00620        locate_user_vcard_in_this_room(&VCMsg, &VCAtt);
00621 
00622        if (VCMsg == NULL) {
00623               AppendImportantMessage(_("An error occurred while trying to create or edit this address book entry."), -1);
00624               select_user_to_edit(username);
00625               FreeStrBuf(&roomname);
00626               return;
00627        }
00628 
00629        do_edit_vcard(vcard_msgnum, "1", 
00630                     VCMsg,
00631                     VCAtt,
00632                     "select_user_to_edit", 
00633                     ChrPtr(roomname));
00634        FreeStrBuf(&roomname);
00635 }
00636 
00637 /*
00638  *  burge a user 
00639  *  username the name of the user to remove
00640  */
00641 void delete_user(char *username) {
00642        StrBuf *Buf;
00643        
00644        Buf = NewStrBuf();
00645        serv_printf("ASUP %s|0|0|0|0|0|", username);
00646        StrBuf_ServGetln(Buf);
00647        GetServerStatusMsg(Buf, NULL, 1, 2);
00648 
00649        select_user_to_edit( bstr("username"));
00650        FreeStrBuf(&Buf);
00651 }
00652               
00653 
00654 void display_edituser(const char *supplied_username, int is_new) {
00655        const char *Pos;
00656        UserListEntry* UL;
00657        StrBuf *Buf;
00658        char username[256];
00659 
00660        if (supplied_username != NULL) {
00661               safestrncpy(username, supplied_username, sizeof username);
00662        }
00663        else {
00664               safestrncpy(username, bstr("username"), sizeof username);
00665        }
00666 
00667        Buf = NewStrBuf();
00668        serv_printf("AGUP %s", username);
00669        StrBuf_ServGetln(Buf);
00670        if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
00671               select_user_to_edit(username);
00672               FreeStrBuf(&Buf);
00673               return;
00674        }
00675        else {
00676               Pos = ChrPtr(Buf) + 4;
00677               UL = NewUserListOneEntry(Buf, Pos);
00678               if ((UL != NULL) && havebstr("edit_abe_button")) {
00679                      display_edit_address_book_entry(username, UL->UID);
00680               }
00681               else if ((UL != NULL) && havebstr("delete_button")) {
00682                      delete_user(username);
00683               }
00684               else if (UL != NULL) {
00685                      WCTemplputParams SubTP;
00686                      memset(&SubTP, 0, sizeof(WCTemplputParams));
00687                      SubTP.Filter.ContextType = CTX_USERLIST;
00688                      SubTP.Context = UL;
00689                      output_headers(1, 0, 0, 0, 1, 0);
00690                      DoTemplate(HKEY("aide_edituser_detailview"), NULL, &SubTP);
00691                      end_burst();
00692               }
00693               DeleteUserListEntry(UL);
00694               
00695        }
00696        FreeStrBuf(&Buf);
00697 }
00698 
00699 /*
00700  *  do the backend operation of the user edit on the server
00701  */
00702 void edituser(void) {
00703        int is_new = 0;
00704        unsigned int flags = 0;
00705        const char *username;
00706 
00707        is_new = ibstr("is_new");
00708        username = bstr("username");
00709 
00710        if (!havebstr("ok_button")) {
00711               AppendImportantMessage(_("Changes were not saved."), -1);
00712        }      
00713        else {
00714               StrBuf *Buf = NewStrBuf();
00715 
00716               flags = ibstr("flags");
00717               if (yesbstr("inetmail")) {
00718                      flags |= US_INTERNET;
00719               }
00720               else {
00721                      flags &= ~US_INTERNET ;
00722               }
00723 
00724               if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
00725                      serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
00726                      StrBuf_ServGetln(Buf);
00727                      if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
00728                             username = bstr("newname");
00729                      }
00730               }
00731 
00732               serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
00733                      username,
00734                      bstr("password"),
00735                      flags,
00736                      bstr("timescalled"),
00737                      bstr("msgsposted"),
00738                      bstr("axlevel"),
00739                      bstr("usernum"),
00740                      bstr("lastcall"),
00741                      bstr("purgedays")
00742               );
00743               StrBuf_ServGetln(Buf);
00744               GetServerStatusMsg(Buf, NULL, 1, 2);
00745               FreeStrBuf(&Buf);
00746        }
00747 
00748        /*
00749         * If we are in the middle of creating a new user, move on to
00750         * the vCard edit screen.
00751         */
00752        if (is_new) {
00753               display_edit_address_book_entry(username, lbstr("usernum") );
00754        }
00755        else {
00756               select_user_to_edit(username);
00757        }
00758 }
00759 
00760 
00761 
00762 /*
00763  *  create a new user
00764  * take the web environment username and create it on the citadel server
00765  */
00766 void create_user(void) {
00767        long FullState;
00768        StrBuf *Buf;
00769        const char *username;
00770 
00771        Buf = NewStrBuf();
00772        username = bstr("username");
00773        serv_printf("CREU %s", username);
00774        StrBuf_ServGetln(Buf);
00775        if (GetServerStatus(Buf, &FullState) == 2) {
00776               AppendImportantMessage(_("A new user has been created."), -1);
00777               display_edituser(username, 1);
00778        }
00779        else if (FullState == 570) {
00780               AppendImportantMessage(_("You are attempting to create a new user from within Citadel "
00781                                     "while running in host based authentication mode.  In this mode, "
00782                                     "you must create new users on the host system, not within Citadel."), 
00783                                    -1);
00784               select_user_to_edit(NULL);
00785        }
00786        else {
00787               AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
00788               select_user_to_edit(NULL);
00789        }
00790        FreeStrBuf(&Buf);
00791 }
00792 
00793 
00794 void _select_user_to_edit(void) {
00795        select_user_to_edit(NULL);
00796 }
00797 
00798 
00799 void _display_edituser(void) {
00800        display_edituser(NULL, 0);
00801 }
00802 
00803 void showuser(void)
00804 {
00805        output_headers(1, 0, 0, 0, 1, 0);
00806        do_template("user_show");
00807        end_burst();
00808 }
00809 
00810 
00811 void 
00812 InitModule_USEREDIT
00813 (void)
00814 {
00815        WebcitAddUrlHandler(HKEY("showuser"), "", 0, showuser, 0);
00816        WebcitAddUrlHandler(HKEY("select_user_to_edit"), "", 0, _select_user_to_edit, 0);
00817        WebcitAddUrlHandler(HKEY("display_edituser"), "", 0, _display_edituser, 0);
00818        WebcitAddUrlHandler(HKEY("edituser"), "", 0, edituser, 0);
00819        WebcitAddUrlHandler(HKEY("create_user"), "", 0, create_user, 0);
00820 
00821        RegisterNamespace("USERLIST:USERNAME",      0, 1, tmplput_USERLIST_UserName, NULL, CTX_USERLIST);
00822        RegisterNamespace("USERLIST:PASSWD",        0, 1, tmplput_USERLIST_Password, NULL, CTX_USERLIST);
00823        RegisterNamespace("USERLIST:ACCLVLNO",      0, 0, tmplput_USERLIST_AccessLevelNo, NULL, CTX_USERLIST);
00824        RegisterNamespace("USERLIST:ACCLVLSTR",     0, 0, tmplput_USERLIST_AccessLevelStr, NULL, CTX_USERLIST);
00825        RegisterNamespace("USERLIST:UID",           0, 0, tmplput_USERLIST_UID, NULL, CTX_USERLIST);
00826        RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, NULL, CTX_USERLIST);
00827        RegisterNamespace("USERLIST:LASTLOGON:NO",  0, 0, tmplput_USERLIST_LastLogonNo, NULL, CTX_USERLIST);
00828        RegisterNamespace("USERLIST:NLOGONS",       0, 0, tmplput_USERLIST_nLogons, NULL, CTX_USERLIST);
00829        RegisterNamespace("USERLIST:NPOSTS",        0, 0, tmplput_USERLIST_nPosts, NULL, CTX_USERLIST);
00830                                               
00831        RegisterNamespace("USERLIST:FLAGS",         0, 0, tmplput_USERLIST_Flags, NULL, CTX_USERLIST);
00832        RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, NULL, CTX_USERLIST);
00833 
00834        RegisterNamespace("USER:BIO", 1, 2, tmplput_USER_BIO,  NULL, CTX_NONE);
00835 
00836        RegisterConditional(HKEY("COND:USERNAME"),  0,    ConditionalUser, CTX_USERLIST);
00837        RegisterConditional(HKEY("COND:USERACCESS"), 0,   ConditionalUserAccess, CTX_USERLIST);
00838        RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
00839        RegisterConditional(HKEY("COND:USERLIST:HAVEBIO"), 0, ConditionalHaveBIO, CTX_USERLIST);
00840 
00841        RegisterConditional(HKEY("COND:USER:PIC"), 1, Conditional_USER_HAS_PIC,  CTX_NONE);
00842 
00843        RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_FLAG_DETECT_GROUPCHANGE);
00844        
00845 
00846 
00847        RegisterSortFunc(HKEY("user:name"),
00848                       HKEY("userlist"),
00849                       CompareUserListName,
00850                       CompareUserListNameRev,
00851                       GroupchangeUserListName,
00852                       CTX_USERLIST);
00853        RegisterSortFunc(HKEY("user:accslvl"),
00854                       HKEY("userlist"),
00855                       CompareAccessLevel,
00856                       CompareAccessLevelRev,
00857                       GroupchangeAccessLevel,
00858                       CTX_USERLIST);
00859 
00860        RegisterSortFunc(HKEY("user:nlogons"),
00861                       HKEY("userlist"),
00862                       ComparenLogons,
00863                       ComparenLogonsRev,
00864                       GroupchangenLogons,
00865                       CTX_USERLIST);
00866 
00867        RegisterSortFunc(HKEY("user:uid"),
00868                       HKEY("userlist"),
00869                       CompareUID,
00870                       CompareUIDRev,
00871                       GroupchangeUID,
00872                       CTX_USERLIST);
00873 
00874        RegisterSortFunc(HKEY("user:lastlogon"),
00875                       HKEY("userlist"),
00876                       CompareLastLogon,
00877                       CompareLastLogonRev,
00878                       GroupchangeLastLogon,
00879                       CTX_USERLIST);
00880 
00881        RegisterSortFunc(HKEY("user:nmsgposts"),
00882                       HKEY("userlist"),
00883                       ComparenPosts,
00884                       ComparenPostsRev,
00885                       GroupchangenPosts,
00886                       CTX_USERLIST);
00887 
00888        REGISTERTokenParamDefine(AxDeleted);
00889        REGISTERTokenParamDefine(AxNewU);
00890        REGISTERTokenParamDefine(AxProbU);
00891        REGISTERTokenParamDefine(AxLocU);
00892        REGISTERTokenParamDefine(AxNetU);
00893        REGISTERTokenParamDefine(AxPrefU);
00894        REGISTERTokenParamDefine(AxAideU);
00895 }
00896