CONF STOREVAL fix off-by-one string termination
[citadel.git] / webcit / vcard_edit.c
index 69b04ca40ded6390a13445b2a2a461f359a6339f..e08a227feb7aafbe201c583cfae377edc31c4535 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996-2012 by the citadel.org team
+ * Copyright (c) 1996-2021 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.
@@ -11,7 +11,7 @@
  */
 
 #include "webcit.h"
-#include "webserver.h"
+
 #include "calendar.h"
 
 CtxType CTX_VCARD = CTX_NONE;
@@ -212,8 +212,7 @@ int preeval_vcard_item(WCTemplateToken *Token)
        TP->Tokens = Token;
        searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0);
        if (searchFieldNo >= VCEnumCounter) {
-               LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP,
-                                "Invalid define");
+               LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP, "Invalid define");
                return 0;
        }
        return 1;
@@ -236,8 +235,7 @@ void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP)
        addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
 
        if (t == NULL) {
-               LogTemplateError(NULL, "VCard item", ERR_NAME, TP,
-                                "Missing context");
+               LogTemplateError(NULL, "VCard item", ERR_NAME, TP, "Missing context");
                return;
        }
 
@@ -318,16 +316,17 @@ int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, W
        long searchType;
        long type = 0;
        void *v;
-       int rc = 0;
        vcField *vf = (vcField*) Context;
+       int rc = 0;
 
        memcpy(&type, key, sizeof(long));
        searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0);
        
        if (vf->Type == searchType) {
                addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
-               if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL)
+               if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL) {
                        return 1;
+               }
        }
        return rc;
 }
@@ -390,6 +389,16 @@ int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP)
        return rc;
 }
 
+
+/* Returns 1 to suppress the "email" fields in the vCard editor, if we're editing a user's contact info.
+ * Returns 0 to present those fields, if we're editing a vCard in an address book.
+ */
+int conditional_VC_SuppressEmailFields(StrBuf *Target, WCTemplputParams *TP)
+{      
+       return(atoi(bstr("suppress_email")));
+}
+
+
 /******************************************************************************
  *              parse one VCard                                               *
  ******************************************************************************/
@@ -426,11 +435,11 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme
                FlushStrBuf(thisVCToken);
                is_qp = 0;
                is_b64 = 0;
-               syslog(LOG_DEBUG, "i: %d oneprop: %s - value: %s", i, v->prop[i].name, v->prop[i].value);
+               // syslog(LOG_DEBUG, "i: %d oneprop: %s - value: %s", i, v->prop[i].name, v->prop[i].value);
                StrBufPlain(thisname, v->prop[i].name, -1);
                StrBufLowerCase(thisname);
                
-               /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken);
+               extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken);
                ntokens = num_tokens(ChrPtr(thisname), ';');
                for (j=0, k=0; j < ntokens && k < 10; ++j) {
                        len = extract_token(buf, ChrPtr(thisname), j, ';', sizeof buf);
@@ -440,7 +449,7 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme
                        else if (!strcasecmp(buf, "encoding=base64")) {
                                is_b64 = 1;
                        }
-                       else{
+                       else {
                                if (StrLength(thisVCToken) > 0) {
                                        StrBufAppendBufPlain(thisVCToken, HKEY(";"), 0);
                                }
@@ -454,7 +463,7 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme
                    (vField != NULL)) {
                        vcField *thisField = (vcField *)vField;
                        StrBuf *ThisFieldStr = NULL;
-                       syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key);
+                       // syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key);
                        switch (thisField->Type) {
                        case StringCluster: {
                                int j = 0;
@@ -464,7 +473,6 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme
                                while (thisField->Sub[j].STR.len > 0) {
                                        StrBufExtract_NextToken(Buf, thisArray, &Pos, ';');
                                        ThisFieldStr = NewStrBufDup(Buf);
-                                       
                                        PutVcardItem(VC, &thisField->Sub[j], ThisFieldStr, is_qp, Swap);
                                        j++;
                                }
@@ -537,18 +545,17 @@ void display_vcard_photo_img(void)
        struct vCard *v;
        char *photosrc;
        const char *contentType;
-       wcsession *WCC = WC;
 
-       msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
+       msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/');
        
        vcard = load_mimepart(msgnum,"1");
        v = VCardLoad(vcard);
        
        photosrc = vcard_get_prop(v, "PHOTO", 1,0,0);
-       FlushStrBuf(WCC->WBuf);
-       StrBufAppendBufPlain(WCC->WBuf, photosrc, -1, 0);
-       if (StrBufDecodeBase64(WCC->WBuf) <= 0) {
-               FlushStrBuf(WCC->WBuf);
+       FlushStrBuf(WC->WBuf);
+       StrBufAppendBufPlain(WC->WBuf, photosrc, -1, 0);
+       if (StrBufDecodeBase64(WC->WBuf) <= 0) {
+               FlushStrBuf(WC->WBuf);
                
                hprintf("HTTP/1.1 500 %s\n","Unable to get photo");
                output_headers(0, 0, 0, 0, 0, 0);
@@ -558,7 +565,7 @@ void display_vcard_photo_img(void)
                end_burst();
                return;
        }
-       contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf));
+       contentType = GuessMimeType(ChrPtr(WC->WBuf), StrLength(WC->WBuf));
        http_transmit_thing(contentType, 0);
        free(v);
        free(photosrc);
@@ -618,7 +625,6 @@ void do_edit_vcard(long msgnum, char *partnum,
                   const char *return_to, 
                   const char *force_room) {
        WCTemplputParams SubTP;
-       wcsession *WCC = WC;
        message_summary *Msg = NULL;
        wc_mime_attachment *VCMime = NULL;
        struct vCard *v;
@@ -654,7 +660,7 @@ void do_edit_vcard(long msgnum, char *partnum,
                        v = VCardLoad(VCAtt->Data);
                }
 
-               parse_vcard(WCC->WBuf, v, ab.VC, NULL);
+               parse_vcard(WC->WBuf, v, ab.VC, NULL);
        
        
                vcard_free(v);
@@ -667,7 +673,7 @@ void do_edit_vcard(long msgnum, char *partnum,
 
                StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL);
 
-               DoTemplate(HKEY("vcard_edit"), WCC->WBuf, &SubTP);
+               DoTemplate(HKEY("vcard_edit"), WC->WBuf, &SubTP);
                UnStackContext(&SubTP);
        }
        DeleteHash(&ab.VC);
@@ -902,7 +908,6 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat,
                            int is_new, 
                            int i)
 {
-       wcsession *WCC = WC;
        WCTemplputParams *TP = NULL;
        WCTemplputParams SubTP;
        vcardview_struct *VS;
@@ -925,18 +930,23 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat,
        abEntry->name = NewStrBuf();
        abEntry->VC = NewHash(0, lFlathash);
        abEntry->ab_msgnum = Msg->msgnum;
-       parse_vcard(WCC->WBuf, v, abEntry->VC, VCMime);
+
+       parse_vcard(WC->WBuf, v, abEntry->VC, VCMime);
 
         memset(&SubTP, 0, sizeof(WCTemplputParams));    
        StackContext(TP, &SubTP, abEntry, CTX_VCARD, 0, NULL);
 
-       DoTemplate(HKEY("vcard_list_name"), WCC->WBuf, &SubTP);
+       // No, don't display the name, it just shits all over the screen
+       // DoTemplate(HKEY("vcard_list_name"), WC->WBuf, &SubTP);
+
        UnStackContext(&SubTP);
 
        if (StrLength(abEntry->name) == 0) {
                StrBufPlain(abEntry->name, _("(no name)"), -1);
        }
 
+       syslog(LOG_DEBUG, "abEntry->name : %s", ChrPtr(abEntry->name));
+
        vcard_free(v);
        
        Put(VS->addrbook, SKEY(abEntry->name), abEntry, deleteAbEnt);
@@ -959,7 +969,6 @@ void do_addrbook_view(vcardview_struct* VS) {
        StrBuf **tablabels;
        int num_ab = GetCount(VS->addrbook);
        HashList *headlines;
-       wcsession *WCC = WC;
 
        WCTemplputParams *TP = NULL;
        WCTemplputParams SubTP;
@@ -1014,11 +1023,10 @@ void do_addrbook_view(vcardview_struct* VS) {
        StrTabbedDialog(WC->WBuf, num_pages, tablabels);
        StackContext(TP, &SubTP, VS->addrbook, CTX_VCARD_LIST, 0, NULL);
 
-       DoTemplate(HKEY("vcard_list"), WCC->WBuf, &SubTP);
+       DoTemplate(HKEY("vcard_list"), WC->WBuf, &SubTP);
        UnStackContext(&SubTP);
        DeleteHash(&headlines);
        free(tablabels);
-       StrBufAppendBufPlain(WCC->WBuf, HKEY("</div>"), 0);/* closes: id=global */
 }
 
 
@@ -1029,10 +1037,12 @@ int vcard_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, lon
        vcardview_struct *VS;
 
        VS = (vcardview_struct*) *ViewSpecific;
-       if (VS->is_singlecard)
+       if (VS->is_singlecard) {
                read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime, NULL);
-       else
+       }
+       else {
                do_addrbook_view(VS);   /* Render the address book */
+       }
        return 0;
 }
 
@@ -1042,11 +1052,12 @@ int vcard_Cleanup(void **ViewSpecific)
 
        VS = (vcardview_struct*) *ViewSpecific;
        wDumpContent(1);
-       if ((VS != NULL) && 
-           (VS->addrbook != NULL))
+       if ((VS != NULL) && (VS->addrbook != NULL)) {
                DeleteHash(&VS->addrbook);
-       if (VS != NULL) 
+       }
+       if (VS != NULL)  {
                free(VS);
+       }
 
        return 0;
 }
@@ -1054,19 +1065,19 @@ int vcard_Cleanup(void **ViewSpecific)
 void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
 {
        wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
-       wcsession *WCC = WC;
-       if (StrLength(Mime->Data) == 0)
+       if (StrLength(Mime->Data) == 0) {
                MimeLoadData(Mime);
+       }
        if (StrLength(Mime->Data) > 0) {
                struct vCard *v;
                StrBuf *Buf;
 
                Buf = NewStrBuf();
                /** If it's my vCard I can edit it */
-               if (    (!strcasecmp(ChrPtr(WCC->CurRoom.name), USERCONFIGROOM))
-                       || ((StrLength(WCC->CurRoom.name) > 11) &&
-                           (!strcasecmp(&(ChrPtr(WCC->CurRoom.name)[11]), USERCONFIGROOM)))
-                       || (WCC->CurRoom.view == VIEW_ADDRESSBOOK)
+               if (    (!strcasecmp(ChrPtr(WC->CurRoom.name), USERCONFIGROOM))
+                       || ((StrLength(WC->CurRoom.name) > 11) &&
+                           (!strcasecmp(&(ChrPtr(WC->CurRoom.name)[11]), USERCONFIGROOM)))
+                       || (WC->CurRoom.view == VIEW_ADDRESSBOOK)
                        ) {
                        StrBufAppendPrintf(Buf, "<a href=\"edit_vcard?msgnum=%ld?partnum=%s\">",
                                Mime->msgnum, ChrPtr(Mime->PartNum));
@@ -1173,7 +1184,9 @@ InitModule_VCARD
        REGISTERTokenParamDefine(TerminateList);
        REGISTERTokenParamDefine(Address);
 
-       RegisterConditional("VC:HAVE:TYPE",      1, conditional_VC_Havetype, CTX_VCARD);
+       RegisterConditional("VC:HAVE:TYPE",                     1,      conditional_VC_Havetype, CTX_VCARD);
+       RegisterConditional("COND:VC:SUPPRESS_EMAIL_FIELDS",    1,      conditional_VC_SuppressEmailFields, CTX_VCARD);
+
        RegisterFilteredIterator("VC:TYPE", 1, DefineToToken, NULL, NULL, NULL, filter_VC_ByType, CTX_VCARD_TYPE, CTX_VCARD, IT_NOFLAG);
        RegisterFilteredIterator("VC:TYPE:ITEMS", 0, NULL, getContextVcard, NULL, NULL, filter_VC_ByContextType, CTX_STRBUF, CTX_VCARD_TYPE, IT_NOFLAG);