home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmime / mimevcrd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  49.3 KB  |  1,676 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "mimevcrd.h"
  20. #include "xpgetstr.h"
  21. #include "xp_core.h"
  22. #include "xp_mem.h"
  23. #include "vcc.h"
  24. #include "vobject.h"
  25.  
  26. #define MIME_SUPERCLASS mimeInlineTextClass
  27. MimeDefClass(MimeInlineTextVCard, MimeInlineTextVCardClass,
  28.              mimeInlineTextVCardClass, &MIME_SUPERCLASS);
  29.  
  30. static int MimeInlineTextVCard_parse_line (char *, int32, MimeObject *);
  31. static int MimeInlineTextVCard_parse_eof (MimeObject *, XP_Bool);
  32. static int MimeInlineTextVCard_parse_begin (MimeObject *obj);
  33.  
  34. static int unique = 0;
  35.  
  36. extern int MK_OUT_OF_MEMORY;
  37.  
  38. extern int MK_LDAP_COMMON_NAME;   
  39. extern int MK_LDAP_FAX_NUMBER;    
  40. extern int MK_LDAP_GIVEN_NAME;    
  41. extern int MK_LDAP_LOCALITY;      
  42. extern int MK_LDAP_PHOTOGRAPH;    
  43. extern int MK_LDAP_EMAIL_ADDRESS; 
  44. extern int MK_LDAP_MANAGER;       
  45. extern int MK_LDAP_ORGANIZATION;  
  46. extern int MK_LDAP_OBJECT_CLASS;  
  47. extern int MK_LDAP_ORG_UNIT;      
  48. extern int MK_LDAP_POSTAL_ADDRESS;
  49. extern int MK_LDAP_SECRETARY;     
  50. extern int MK_LDAP_SURNAME;       
  51. extern int MK_LDAP_STREET;        
  52. extern int MK_LDAP_PHONE_NUMBER;  
  53. extern int MK_LDAP_CAR_LICENSE;
  54. extern int MK_LDAP_BUSINESS_CAT;
  55. extern int MK_LDAP_DEPT_NUMBER;
  56. extern int MK_LDAP_DESCRIPTION;
  57. extern int MK_LDAP_EMPLOYEE_TYPE;
  58. extern int MK_LDAP_POSTAL_CODE;
  59. extern int MK_LDAP_TITLE;
  60. extern int MK_LDAP_REGION;
  61. extern int MK_LDAP_DOM_TYPE;
  62. extern int MK_LDAP_INTL_TYPE;
  63. extern int MK_LDAP_POSTAL_TYPE;
  64. extern int MK_LDAP_PARCEL_TYPE;
  65. extern int MK_LDAP_WORK_TYPE;
  66. extern int MK_LDAP_HOME_TYPE;
  67. extern int MK_LDAP_PREF_TYPE;
  68. extern int MK_LDAP_VOICE_TYPE;
  69. extern int MK_LDAP_FAX_TYPE;
  70. extern int MK_LDAP_MSG_TYPE;
  71. extern int MK_LDAP_CELL_TYPE;
  72. extern int MK_LDAP_PAGER_TYPE;
  73. extern int MK_LDAP_BBS_TYPE;
  74. extern int MK_LDAP_MODEM_TYPE;
  75. extern int MK_LDAP_CAR_TYPE;
  76. extern int MK_LDAP_ISDN_TYPE;
  77. extern int MK_LDAP_VIDEO_TYPE;
  78. extern int MK_LDAP_AOL_TYPE;
  79. extern int MK_LDAP_APPLELINK_TYPE;
  80. extern int MK_LDAP_ATTMAIL_TYPE;
  81. extern int MK_LDAP_CSI_TYPE;
  82. extern int MK_LDAP_EWORLD_TYPE;
  83. extern int MK_LDAP_INTERNET_TYPE;
  84. extern int MK_LDAP_IBMMAIL_TYPE;
  85. extern int MK_LDAP_MCIMAIL_TYPE;
  86. extern int MK_LDAP_POWERSHARE_TYPE;
  87. extern int MK_LDAP_PRODIGY_TYPE;
  88. extern int MK_LDAP_TLX_TYPE;
  89. extern int MK_LDAP_MIDDLE_NAME;
  90. extern int MK_LDAP_NAME_PREFIX;
  91. extern int MK_LDAP_NAME_SUFFIX;
  92. extern int MK_LDAP_TZ;
  93. extern int MK_LDAP_GEO;
  94. extern int MK_LDAP_SOUND;
  95. extern int MK_LDAP_REVISION;
  96. extern int MK_LDAP_VERSION;
  97. extern int MK_LDAP_KEY;
  98. extern int MK_LDAP_LOGO;
  99. extern int MK_LDAP_X400;
  100. extern int MK_LDAP_BIRTHDAY;
  101. extern int MK_LDAP_ADDRESS;
  102. extern int MK_LDAP_LABEL;
  103. extern int MK_LDAP_MAILER;
  104. extern int MK_LDAP_ROLE;
  105. extern int MK_LDAP_UPDATEURL;
  106. extern int MK_LDAP_COOLTALKADDRESS;
  107. extern int MK_LDAP_USEHTML;
  108. extern int MK_ADDR_VIEW_COMPLETE_VCARD;
  109. extern int MK_ADDR_VIEW_CONDENSED_VCARD;
  110. extern int MK_MSG_ADD_TO_ADDR_BOOK;
  111. extern int MK_ADDR_DEFAULT_DLS;
  112. extern int MK_ADDR_SPECIFIC_DLS;
  113. extern int MK_ADDR_HOSTNAMEIP;
  114. extern int MK_ADDR_CONFINFO;
  115. extern int MK_ADDR_ADDINFO;
  116.  
  117. static int BeginVCard (MimeObject *obj);
  118. static int EndVCard (MimeObject *obj);
  119. static int WriteOutVCard (MimeObject *obj, VObject* v);
  120. static int WriteOutEachVCardProperty (MimeObject *obj, VObject* v, int* numEmail);
  121. static int WriteOutVCardProperties (MimeObject *obj, VObject* v, int* numEmail);
  122. static int WriteLineToStream (MimeObject *obj, const char *line);
  123.  
  124. static void GetEmailProperties (VObject* o, char ** attribName);
  125. static void GetTelephoneProperties (VObject* o, char ** attribName);
  126. static void GetAddressProperties (VObject* o, char ** attribName);
  127. static int WriteValue (MimeObject *obj, const char *);
  128. static int WriteAttribute (MimeObject *obj, const char *);
  129. static int WriteOutVCardPhoneProperties (MimeObject *obj, VObject* v);
  130. static int WriteOutEachVCardPhoneProperty (MimeObject *obj, VObject* o);
  131.  
  132. typedef struct
  133.     {
  134.         const char *attributeName;
  135.         int resourceId;
  136.     } AttributeName;
  137.  
  138. #define kNumAttributes 12
  139.  
  140. static int
  141. MimeInlineTextVCardClassInitialize(MimeInlineTextVCardClass *class)
  142. {
  143.   MimeObjectClass *oclass = (MimeObjectClass *) class;
  144.   XP_ASSERT(!oclass->class_initialized);
  145.   oclass->parse_begin = MimeInlineTextVCard_parse_begin;
  146.   oclass->parse_line  = MimeInlineTextVCard_parse_line;
  147.   oclass->parse_eof   = MimeInlineTextVCard_parse_eof;
  148.  
  149. return 0;
  150. }
  151.  
  152. static int
  153. MimeInlineTextVCard_parse_begin (MimeObject *obj)
  154. {
  155.     int status = ((MimeObjectClass*)&mimeLeafClass)->parse_begin(obj);
  156.     MimeInlineTextVCardClass *class;
  157.     if (status < 0) return status;
  158.  
  159.     if (!obj->output_p) return 0;
  160.     if (!obj->options || !obj->options->write_html_p) return 0;
  161.  
  162.     /* This is a fine place to write out any HTML before the real meat begins.
  163.        In this sample code, we tell it to start a table. */
  164.  
  165.     class = ((MimeInlineTextVCardClass *) obj->class);
  166.     /* initialize vcard string to empty; */
  167.     StrAllocCopy(class->vCardString, "");
  168.  
  169.     return 0;
  170. }
  171.  
  172.  
  173. static int
  174. MimeInlineTextVCard_parse_line (char *line, int32 length, MimeObject *obj)
  175. {
  176.     /* This routine gets fed each line of data, one at a time.  In my
  177.        sample, I spew it out as a table row, putting everything
  178.        between colons in its own table cell.*/
  179.  
  180.     char* linestring;
  181.     MimeInlineTextVCardClass *class = ((MimeInlineTextVCardClass *) obj->class);
  182.  
  183.     if (!obj->output_p) return 0;
  184.     if (!obj->options || !obj->options->output_fn) return 0;
  185.     if (!obj->options->write_html_p) {
  186.         return MimeObject_write(obj, line, length, TRUE);
  187.     }
  188.  
  189.     linestring = (char *) XP_ALLOC (length + 1);
  190.  
  191.     if (linestring) {
  192.         XP_STRNCPY_SAFE((char *)linestring, line, length + 1);
  193.         StrAllocCat (class->vCardString, linestring);
  194.         XP_FREE (linestring);
  195.     }
  196.  
  197.     return 0;
  198. }
  199.  
  200.  
  201. static int
  202. MimeInlineTextVCard_parse_eof (MimeObject *obj, XP_Bool abort_p)
  203. {
  204.     int status = 0;
  205.     MimeInlineTextVCardClass *class = ((MimeInlineTextVCardClass *) obj->class);
  206.     VObject *t, *v;
  207.  
  208.     if (obj->closed_p) return 0;
  209.  
  210.     /* Run parent method first, to flush out any buffered data. */
  211.     status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
  212.     if (status < 0) return status;
  213.  
  214.     if (!class->vCardString) return 0;
  215.  
  216.     v = Parse_MIME(class->vCardString, XP_STRLEN(class->vCardString));
  217.  
  218.     if (class->vCardString) {
  219.         XP_FREE ((char*) class->vCardString);
  220.         class->vCardString = NULL;
  221.     }
  222.  
  223.     if (obj->output_p && obj->options && obj->options->write_html_p) {
  224.         /* This is a fine place to write any closing HTML.  In fact, you may
  225.            want all the writing to be here, and all of the above would just
  226.            collect data into datastructures, though that isn't very
  227.            "streaming". */
  228.         t = v;
  229.         while (v && status >= 0) {
  230.             /* write out html */
  231.             status = WriteOutVCard (obj, v);
  232.             /* parse next vcard incase they're embedded */
  233.             v = nextVObjectInList(v);
  234.         }
  235.  
  236.         cleanVObject(t);
  237.     }
  238.     if (status < 0) return status;
  239.  
  240.     return 0;
  241. }
  242.  
  243. static int WriteEachLineToStream (MimeObject *obj, const char *line)
  244. {
  245.     int status = 0;
  246.     char *htmlLine;
  247.     int htmlLen = XP_STRLEN(line) + 1;
  248.  
  249.     htmlLine = (char *) XP_ALLOC (htmlLen);
  250.     if (htmlLine)
  251.     {
  252.         htmlLine[0] = '\0';
  253.         XP_STRCAT (htmlLine, line);
  254.         status = MimeObject_write(obj, htmlLine, XP_STRLEN(htmlLine), TRUE);
  255. #ifdef DEBUG_mwatkins
  256.         if (XP_STRLEN (htmlLine) < 500)
  257.             XP_Trace("%s%c", htmlLine, '\n');
  258. #endif
  259.         XP_FREE ((void*) htmlLine);
  260.     }
  261.     else
  262.         status = MK_OUT_OF_MEMORY;
  263.  
  264.     return status;
  265. }
  266.  
  267. static int OutputTable (MimeObject *obj, XP_Bool endTable, XP_Bool border, char *cellspacing, char *cellpadding, char *bgcolor)
  268. {
  269.     int status = 0;
  270.     char * htmlLine = NULL;
  271.  
  272.     if (endTable)
  273.     {
  274.         status = WriteEachLineToStream (obj, "</TABLE>");
  275.     }
  276.     else
  277.     {
  278.         int htmlLen = XP_STRLEN("<TABLE>") + 1;
  279.         if (border)
  280.             htmlLen += XP_STRLEN (" BORDER");
  281.         if (cellspacing)
  282.             htmlLen += XP_STRLEN(" CELLSPACING=") + XP_STRLEN(cellspacing);
  283.         if (cellpadding)
  284.             htmlLen += XP_STRLEN(" CELLPADDING=") + XP_STRLEN(cellpadding);
  285.         if (bgcolor)
  286.             htmlLen += XP_STRLEN(" BGCOLOR=") + XP_STRLEN(bgcolor);
  287.         if (border || cellspacing || cellpadding || bgcolor)
  288.             htmlLen++;
  289.  
  290.         htmlLine = (char *) XP_ALLOC (htmlLen);
  291.         if (htmlLine)
  292.         {
  293.             htmlLine[0] = '\0';
  294.             XP_STRCAT (htmlLine, "<TABLE");
  295.             if (border)
  296.                 XP_STRCAT (htmlLine, " BORDER");
  297.             if (cellspacing)
  298.             {    
  299.                 XP_STRCAT (htmlLine, " CELLSPACING=");
  300.                 XP_STRCAT (htmlLine, cellspacing);
  301.             }
  302.             if (cellpadding)
  303.             {    
  304.                 XP_STRCAT (htmlLine, " CELLPADDING=");
  305.                 XP_STRCAT (htmlLine, cellpadding);
  306.             }
  307.             if (bgcolor)
  308.             {    
  309.                 XP_STRCAT (htmlLine, " BGCOLOR=");
  310.                 XP_STRCAT (htmlLine, bgcolor);
  311.             }
  312.  
  313.             if (border || cellspacing || cellpadding || bgcolor)
  314.                 XP_STRCAT (htmlLine, " ");
  315.  
  316.             XP_STRCAT (htmlLine, ">");
  317.  
  318.             status = MimeObject_write(obj, htmlLine, XP_STRLEN(htmlLine), TRUE);
  319. #ifdef DEBUG_mwatkins
  320.             XP_Trace("%s%c", htmlLine, '\n');
  321. #endif
  322.             XP_FREE ((void*) htmlLine);
  323.         }
  324.         else
  325.             status = MK_OUT_OF_MEMORY;
  326.     }    
  327.     return status;
  328. }
  329.  
  330. static int OutputTableRowOrData(MimeObject *obj, XP_Bool outputRow, 
  331.                                 XP_Bool end, char * align, 
  332.                                 char* valign, char* colspan,
  333.                                 char* width)
  334. {
  335.     int status = 0;
  336.     char * htmlLine = NULL;
  337.  
  338.     if (end)
  339.         if (outputRow)
  340.             status = WriteEachLineToStream (obj, "</TR>");
  341.         else
  342.             status = WriteEachLineToStream (obj, "</TD>");
  343.     else
  344.     {
  345.         int htmlLen = XP_STRLEN("<TR>") + 1;
  346.         if (align)
  347.             htmlLen += XP_STRLEN(" ALIGN=") + XP_STRLEN(align);
  348.         if (colspan)
  349.             htmlLen += XP_STRLEN(" COLSPAN=") + XP_STRLEN(colspan);
  350.         if (width)
  351.             htmlLen += XP_STRLEN(" WIDTH=") + XP_STRLEN(width);
  352.         if (valign)
  353.             htmlLen += XP_STRLEN(" VALIGN=") + XP_STRLEN(valign);
  354.         if (align || valign || colspan || width)
  355.             htmlLen++;
  356.  
  357.         htmlLine = (char *) XP_ALLOC (htmlLen);
  358.         if (htmlLine)
  359.         {
  360.             htmlLine[0] = '\0';
  361.             if (outputRow)
  362.                 XP_STRCAT (htmlLine, "<TR");
  363.             else
  364.                 XP_STRCAT (htmlLine, "<TD");
  365.             if (align)
  366.             {    
  367.                 XP_STRCAT (htmlLine, " ALIGN=");
  368.                 XP_STRCAT (htmlLine, align);
  369.             }
  370.             if (valign)
  371.             {    
  372.                 XP_STRCAT (htmlLine, " VALIGN=");
  373.                 XP_STRCAT (htmlLine, valign);
  374.             }
  375.             if (colspan)
  376.             {    
  377.                 XP_STRCAT (htmlLine, " COLSPAN=");
  378.                 XP_STRCAT (htmlLine, colspan);
  379.             }
  380.             if (width)
  381.             {    
  382.                 XP_STRCAT (htmlLine, " WIDTH=");
  383.                 XP_STRCAT (htmlLine, width);
  384.             }
  385.             if (align || valign || colspan || width)
  386.                 XP_STRCAT (htmlLine, " ");
  387.  
  388.             XP_STRCAT (htmlLine, ">");
  389.  
  390.             status = MimeObject_write(obj, htmlLine, XP_STRLEN(htmlLine), TRUE);
  391. #ifdef DEBUG_mwatkins
  392.             XP_Trace("%s%c", htmlLine, '\n');
  393. #endif
  394.             XP_FREE ((void*) htmlLine);
  395.         }
  396.         else
  397.             status = MK_OUT_OF_MEMORY;
  398.     }
  399.  
  400.     return status;
  401. }
  402.  
  403.  
  404. static int OutputFont(MimeObject *obj, XP_Bool endFont, char * size, char* color)
  405. {
  406.     int status = 0;
  407.     char * htmlLine = NULL;
  408.  
  409.     if (endFont)
  410.         status = WriteEachLineToStream (obj, "</FONT>");
  411.     else
  412.     {
  413.         int htmlLen = XP_STRLEN("<FONT>") + 1;
  414.         if (size)
  415.             htmlLen += XP_STRLEN(" SIZE=") + XP_STRLEN(size);
  416.         if (color)
  417.             htmlLen += XP_STRLEN(" COLOR=") + XP_STRLEN(color);
  418.         if (size || color)
  419.             htmlLen++;
  420.  
  421.         htmlLine = (char *) XP_ALLOC (htmlLen);
  422.         if (htmlLine)
  423.         {
  424.             htmlLine[0] = '\0';
  425.                 XP_STRCAT (htmlLine, "<FONT");
  426.             if (size)
  427.             {    
  428.                 XP_STRCAT (htmlLine, " SIZE=");
  429.                 XP_STRCAT (htmlLine, size);
  430.             }
  431.             if (color)
  432.             {    
  433.                 XP_STRCAT (htmlLine, " COLOR=");
  434.                 XP_STRCAT (htmlLine, color);
  435.             }
  436.             if (size || color)
  437.                 XP_STRCAT (htmlLine, " ");
  438.  
  439.             XP_STRCAT (htmlLine, ">");
  440.  
  441.             status = MimeObject_write(obj, htmlLine, XP_STRLEN(htmlLine), TRUE);
  442. #ifdef DEBUG_mwatkins
  443.             XP_Trace("%s%c", htmlLine, '\n');
  444. #endif
  445.             XP_FREE ((void*) htmlLine);
  446.         }
  447.         else
  448.             status = MK_OUT_OF_MEMORY;
  449.     }
  450.  
  451.     return status;
  452. }
  453.  
  454. static int OutputVcardAttribute(MimeObject *obj, VObject *v, const char* id) 
  455. {
  456.     int status = 0;
  457.     VObject *prop = NULL;
  458.     char *string = NULL;
  459.  
  460.     prop = isAPropertyOf(v, id);
  461.     if (prop)
  462.         if (VALUE_TYPE(prop))
  463.         {
  464.             string = fakeCString (vObjectUStringZValue(prop));
  465.             if (string) {
  466.                 status = OutputFont(obj, FALSE, "-1", NULL);
  467.                 if (status < 0) {
  468.                     XP_FREEIF (string);
  469.                     return status;
  470.                 }
  471.                 status = WriteLineToStream (obj, string);
  472.                 XP_FREEIF (string);
  473.                 if (status < 0) return status;
  474.                 status = OutputFont(obj, TRUE, NULL, NULL);
  475.                 if (status < 0) return status;
  476.             }
  477.         }
  478.  
  479.     return 0;
  480. }
  481.  
  482.  
  483. static int OutputBasicVcard(MimeObject *obj, VObject *v)
  484. {
  485.     int status = 0;
  486.     char * htmlLine1 = NULL;
  487.     char * htmlLine2 = NULL;
  488.     char * htmlLine = NULL;
  489.     VObject *prop = NULL;
  490.     VObject* prop2 = NULL;
  491.     char * urlstring = NULL;
  492.     char * namestring = NULL;
  493.     char * emailstring = NULL;
  494.  
  495.     /* get the name and email */
  496.     prop = isAPropertyOf(v, VCFullNameProp);
  497.     if (prop)
  498.     {
  499.         if (VALUE_TYPE(prop))
  500.         {
  501.             namestring  = fakeCString (vObjectUStringZValue(prop));
  502.             if (namestring)
  503.             {
  504.                 prop = isAPropertyOf(v, VCURLProp);
  505.                 if (prop)
  506.                 {
  507.                     urlstring  = fakeCString (vObjectUStringZValue(prop));
  508.                     if (urlstring)
  509.                         htmlLine1 = PR_smprintf ("<A HREF=""%s"">%s</A> ", urlstring, namestring);
  510.                     else
  511.                         htmlLine1 = PR_smprintf ("%s ", namestring);
  512.                     XP_FREEIF (urlstring);
  513.                 }
  514.                 else
  515.                     htmlLine1 = PR_smprintf ("%s ", namestring);
  516.  
  517.                 /* get the email address */
  518.                 prop = isAPropertyOf(v, VCEmailAddressProp);
  519.                 if (prop)
  520.                 {
  521.                     emailstring  = fakeCString (vObjectUStringZValue(prop));
  522.                     if (emailstring)
  523.                     {
  524.                         /* if its an internet address prepend the mailto url */
  525.                         prop2 = isAPropertyOf(prop, VCInternetProp);
  526.                         if (prop2)
  527.                             htmlLine2 = PR_smprintf ("<<A HREF=""mailto:%s"">%s</A>>", emailstring, emailstring);
  528.                         else
  529.                             htmlLine2 = PR_smprintf ("%s", emailstring);
  530.                         XP_FREEIF (emailstring);
  531.                     }
  532.                 }
  533.  
  534.                 if (!htmlLine1 && !htmlLine2)
  535.                 {
  536.                     XP_FREEIF (htmlLine1);
  537.                     XP_FREEIF (htmlLine2);
  538.                     return MK_OUT_OF_MEMORY;
  539.                 }
  540.                 else
  541.                 {
  542.                     htmlLine = StrAllocCat (htmlLine, htmlLine1);
  543.                     htmlLine = StrAllocCat (htmlLine, htmlLine2);
  544.                 }
  545.  
  546.                 XP_FREEIF (htmlLine1);
  547.                 XP_FREEIF (htmlLine2);
  548.                 XP_FREEIF (namestring);
  549.             }
  550.         }
  551.     }
  552.  
  553.     status = OutputTable (obj, FALSE, FALSE, "0", "0", NULL);
  554.     if (status < 0) {
  555.         XP_FREEIF (htmlLine); 
  556.         return status;
  557.     }
  558.     if (htmlLine)
  559.     {
  560.         status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  561.         if (status < 0) {
  562.             XP_FREE (htmlLine);
  563.             return status;
  564.         }
  565.         status = OutputTableRowOrData (obj, FALSE, FALSE, NULL, NULL, NULL, NULL);
  566.         if (status < 0) {
  567.             XP_FREE (htmlLine);
  568.             return status;
  569.         }
  570.  
  571.         status = WriteLineToStream (obj, htmlLine);
  572.         XP_FREE (htmlLine); 
  573.         if (status < 0) return status;
  574.         status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  575.         if (status < 0) return status;
  576.         status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  577.         if (status < 0) return status;
  578.     }
  579.     else
  580.         status = MK_OUT_OF_MEMORY;
  581.  
  582.     status = OutputTableRowOrData(obj, TRUE, FALSE, NULL, NULL, NULL, NULL);
  583.     if (status < 0) return status;
  584.     status = OutputTableRowOrData (obj, FALSE, FALSE, NULL, NULL, NULL, NULL);
  585.     if (status < 0) return status;
  586.     /* output the title */
  587.     status = OutputVcardAttribute (obj, v, VCTitleProp);
  588.     if (status < 0) return status;
  589.     /* write out the org name and company name */
  590.     prop = isAPropertyOf(v, VCOrgProp);
  591.     if (prop)
  592.     {
  593.         status = OutputVcardAttribute (obj, prop, VCOrgNameProp);
  594.         if (status < 0) return status;
  595.         status = OutputVcardAttribute (obj, prop, VCOrgUnitProp);
  596.         if (status < 0) return status;
  597.         status = OutputVcardAttribute (obj, prop, VCOrgUnit2Prop);
  598.         if (status < 0) return status;
  599.         status = OutputVcardAttribute (obj, prop, VCOrgUnit3Prop);
  600.         if (status < 0) return status;
  601.     }
  602.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  603.     if (status < 0) return status;
  604.     status = OutputTableRowOrData (obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  605.     if (status < 0) return status;
  606.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  607.     if (status < 0) return status;
  608.  
  609.     return 0;
  610. }
  611.  
  612. static int OutputAdvancedVcard(MimeObject *obj, VObject *v)
  613. {
  614.     int status = 0;
  615.     char * htmlLine1 = NULL;
  616.     char * htmlLine2 = NULL;
  617.     VObject *prop = NULL;
  618.     VObject* prop2 = NULL;
  619.     char * urlstring = NULL;
  620.     char * namestring = NULL;
  621.     char * emailstring = NULL;
  622.     int numEmail = 0;
  623.  
  624.     status = OutputTable (obj, FALSE, FALSE, "0", "0", NULL);
  625.     if (status < 0) return status;
  626.     /* beginning of first row */
  627.     status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  628.     if (status < 0) return status;
  629.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", "3", NULL);
  630.     if (status < 0) return status;
  631.  
  632.     /* get the name and email */
  633.     prop = isAPropertyOf(v, VCFullNameProp);
  634.     if (prop)
  635.     {
  636.         if (VALUE_TYPE(prop))
  637.         {
  638.             namestring  = fakeCString (vObjectUStringZValue(prop));
  639.             if (namestring)
  640.             {
  641.                 prop = isAPropertyOf(v, VCURLProp);
  642.                 if (prop)
  643.                 {
  644.                     urlstring  = fakeCString (vObjectUStringZValue(prop));
  645.                     if (urlstring)
  646.                         htmlLine1 = PR_smprintf ("<A HREF=""%s"">%s</A> ", urlstring, namestring);
  647.                     else
  648.                         htmlLine1 = PR_smprintf ("%s ", namestring);
  649.                     XP_FREEIF (urlstring);
  650.                 }
  651.                 else
  652.                     htmlLine1 = PR_smprintf ("%s ", namestring);
  653.  
  654.                 XP_FREEIF (namestring);
  655.             }
  656.             if (!htmlLine1)
  657.             {
  658.                 return MK_OUT_OF_MEMORY;
  659.             }
  660.         }
  661.     }
  662.     /* output the name if there was one */
  663.     if (htmlLine1)
  664.     {
  665.         status = WriteLineToStream (obj, htmlLine1);
  666.         XP_FREEIF (htmlLine1);
  667.         if (status < 0) return status;
  668.     }
  669.  
  670.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  671.     if (status < 0) return status;
  672.     status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  673.     if (status < 0) return status;
  674.     
  675.     /* beginning of second row */
  676.     status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  677.     if (status < 0) return status;
  678.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  679.     if (status < 0) return status;
  680.     /* output the title */
  681.     status = OutputVcardAttribute (obj, v, VCTitleProp);
  682.     if (status < 0) return status;
  683.     /* write out the org name and company name */
  684.     prop = isAPropertyOf(v, VCOrgProp);
  685.     if (prop)
  686.     {
  687.         status = OutputVcardAttribute (obj, prop, VCOrgNameProp);
  688.         if (status < 0) return status;
  689.         status = OutputVcardAttribute (obj, prop, VCOrgUnitProp);
  690.         if (status < 0) return status;
  691.         status = OutputVcardAttribute (obj, prop, VCOrgUnit2Prop);
  692.         if (status < 0) return status;
  693.         status = OutputVcardAttribute (obj, prop, VCOrgUnit3Prop);
  694.         if (status < 0) return status;
  695.     }
  696.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  697.     if (status < 0) return status;
  698.  
  699.     status = OutputTableRowOrData (obj, FALSE, FALSE , "LEFT", "TOP", NULL, "\"10\"");
  700.     if (status < 0) return status;
  701.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  702.     if (status < 0) return status;
  703.  
  704.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  705.     if (status < 0) return status;
  706.  
  707.     /* get the email address */
  708.     prop = isAPropertyOf(v, VCEmailAddressProp);
  709.     if (prop)
  710.     {
  711.         emailstring  = fakeCString (vObjectUStringZValue(prop));
  712.         if (emailstring)
  713.         {
  714.             numEmail++;
  715.             /* if its an internet address prepend the mailto url */
  716.             prop2 = isAPropertyOf(prop, VCInternetProp);
  717.             if (prop2)
  718.                 htmlLine2 = PR_smprintf ("<<A HREF=""mailto:%s"">%s</A>>", emailstring, emailstring);
  719.             else
  720.                 htmlLine2 = PR_smprintf ("%s", emailstring);
  721.  
  722.             XP_FREEIF (emailstring);
  723.         }
  724.         if (!htmlLine2)
  725.         {
  726.             return MK_OUT_OF_MEMORY;
  727.         }
  728.     }
  729.     /* output email address */
  730.     if (htmlLine2)
  731.     {
  732.         status = OutputFont(obj, FALSE, "-1", NULL);
  733.         if (status < 0) {
  734.             XP_FREEIF (htmlLine2);
  735.             return status;
  736.         }
  737.         status = WriteLineToStream (obj, htmlLine2);
  738.         XP_FREEIF (htmlLine2);
  739.         if (status < 0) return status;
  740.         status = OutputFont(obj, TRUE, NULL, NULL);
  741.         if (status < 0) return status;
  742.         /* output html mail setting only if its true */
  743.         prop = isAPropertyOf(v, VCUseHTML);
  744.         if (prop)
  745.         {
  746.             if (VALUE_TYPE(prop))
  747.             {
  748.                 namestring  = fakeCString (vObjectUStringZValue(prop));
  749.                 if (namestring)
  750.                     if (strcasecomp (namestring, "TRUE") == 0)
  751.                     {
  752.                         XP_FREEIF (namestring);
  753.                         status = OutputFont(obj, FALSE, "-1", NULL);
  754.                         if (status < 0) return status;
  755.                         status = WriteLineToStream (obj, XP_GetString (MK_LDAP_USEHTML));
  756.                         if (status < 0) return status;
  757.                         status = OutputFont(obj, TRUE, NULL, NULL);
  758.                         if (status < 0) return status;
  759.                     }
  760.                     else
  761.                         XP_FREEIF (namestring);
  762.             }
  763.         }
  764.     }
  765.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  766.     if (status < 0) return status;
  767.     status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  768.     if (status < 0) return status;
  769.  
  770.     /* beginning of third row */
  771.     /* write out address information if we have any */
  772.     status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  773.     if (status < 0) return status;
  774.     /* first column */
  775.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  776.     if (status < 0) return status;
  777.     prop = isAPropertyOf(v, VCAdrProp);
  778.     if (prop)
  779.     {
  780.         status = OutputVcardAttribute (obj, prop, VCPostalBoxProp);
  781.         if (status < 0) return status;
  782.         status = OutputVcardAttribute (obj, prop, VCExtAddressProp);
  783.         if (status < 0) return status;
  784.         status = OutputVcardAttribute (obj, prop, VCStreetAddressProp);
  785.         if (status < 0) return status;
  786.         status = OutputVcardAttribute (obj, prop, VCCityProp);
  787.         if (status < 0) return status;
  788.         status = OutputVcardAttribute (obj, prop, VCRegionProp);
  789.         if (status < 0) return status;
  790.         status = OutputVcardAttribute (obj, prop, VCPostalCodeProp);
  791.         if (status < 0) return status;
  792.         status = OutputVcardAttribute (obj, prop, VCCountryNameProp);
  793.         if (status < 0) return status;
  794.     }
  795.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  796.     if (status < 0) return status;
  797.  
  798.     /* second column */
  799.     status = OutputTableRowOrData (obj, FALSE, FALSE , NULL, NULL, NULL, NULL);
  800.     if (status < 0) return status;
  801.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  802.     if (status < 0) return status;
  803.  
  804.     /* third column */
  805.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  806.     if (status < 0) return status;
  807.     /* output telephone fields */
  808.     status = WriteOutVCardPhoneProperties (obj, v);
  809.     if (status < 0) return status;
  810.     /* output conference fields */
  811.     status = OutputFont(obj, FALSE, "-1", NULL);
  812.     if (status < 0) return status;
  813.     prop = isAPropertyOf(v, VCCooltalk);
  814.     if (prop)
  815.     {
  816.         WriteLineToStream (obj, XP_GetString (MK_ADDR_CONFINFO));
  817.         if (status < 0) return status;
  818.         prop2 = isAPropertyOf(prop, VCUseServer);
  819.         if (prop2)
  820.         {
  821.             if (VALUE_TYPE(prop2)) {
  822.                 namestring  = fakeCString (vObjectUStringZValue(prop2));
  823.                 if (XP_STRCMP (namestring, "0") == 0)
  824.                     status = WriteLineToStream (obj, XP_GetString (MK_ADDR_DEFAULT_DLS));
  825.                 else {
  826.                     if (XP_STRCMP (namestring, "1") == 0)
  827.                         status = WriteLineToStream (obj, XP_GetString (MK_ADDR_SPECIFIC_DLS));
  828.                     else
  829.                         if (XP_STRCMP (namestring, "2") == 0)
  830.                             status = WriteLineToStream (obj, XP_GetString (MK_ADDR_HOSTNAMEIP));
  831.                 }
  832.                 XP_FREEIF (namestring);
  833.                 if (status < 0) return status;
  834.             }
  835.         }
  836.         status = OutputVcardAttribute (obj, prop, VCCooltalkAddress);
  837.         if (status < 0) return status;
  838.     }
  839.  
  840.     status = OutputFont(obj, TRUE, NULL, NULL);
  841.     if (status < 0) return status;
  842.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  843.     if (status < 0) return status;
  844.  
  845.     status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  846.     if (status < 0) return status;
  847.  
  848.     /* beginning of last row */
  849.     /* output notes field */
  850.     prop = isAPropertyOf(v, VCCommentProp);
  851.     if (prop)
  852.     {
  853.         status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  854.         if (status < 0) return status;
  855.         status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", "3", NULL);
  856.         if (status < 0) return status;
  857.         status = OutputVcardAttribute (obj, v, VCCommentProp);
  858.         if (status < 0) return status;
  859.         status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  860.         if (status < 0) return status;
  861.         status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  862.         if (status < 0) return status;
  863.     }
  864.  
  865.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  866.     if (status < 0) return status;
  867.  
  868.     /* output second table containing all the additional info */
  869.     status = OutputTable (obj, FALSE, FALSE, "0", "0", NULL);
  870.     if (status < 0) return status;
  871.     /* beginning of first row */
  872.     status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  873.     if (status < 0) return status;
  874.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", "2", NULL);
  875.     if (status < 0) return status;
  876.     /* output the additional info header */
  877.     status = OutputFont(obj, FALSE, "-1", NULL);
  878.     if (status < 0) return status;
  879.     status = WriteLineToStream (obj, XP_GetString (MK_ADDR_ADDINFO));
  880.     if (status < 0) return status;
  881.     status = OutputFont(obj, TRUE, NULL, NULL);
  882.     if (status < 0) return status;
  883.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  884.     if (status < 0) return status;
  885.     status = OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  886.     if (status < 0) return status;
  887.     
  888.     /* beginning of remaining rows */
  889.     status = WriteOutVCardProperties (obj, v, &numEmail);
  890.     if (status < 0) return status;
  891.  
  892.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  893.     if (status < 0) return status;
  894.  
  895.     return 0;
  896. }
  897.  
  898. static int OutputButtons(MimeObject *obj, XP_Bool basic, VObject *v)
  899. {
  900.     int status = 0;
  901.     char * htmlLine = NULL;
  902.     char * htmlLine1 = NULL;
  903.     char * htmlLine2 = NULL;
  904.     char* vCard = NULL;
  905.     char* vEscCard = NULL;
  906.     int len = 0;
  907.  
  908.     if (!obj->options->output_vcard_buttons_p)
  909.         return status;
  910.  
  911.     vCard = writeMemVObjects(0, &len, v, FALSE);
  912.  
  913.     if (!vCard)
  914.         return MK_OUT_OF_MEMORY;
  915.  
  916.     vEscCard = NET_Escape (vCard, URL_XALPHAS);
  917.  
  918.     XP_FREEIF (vCard);
  919.  
  920.     if (!vEscCard)
  921.         return MK_OUT_OF_MEMORY;
  922.  
  923.     if (basic)
  924.     {
  925.         htmlLine1 = PR_smprintf ("<FORM name=form1><INPUT type=reset value=\\\"%s\\\" onClick=\\\"showAdvanced%d();\\\"></INPUT></FORM>", 
  926.             XP_GetString(MK_ADDR_VIEW_COMPLETE_VCARD), unique);
  927.         htmlLine2 = PR_smprintf ("<FORM name=form1 METHOD=get ACTION=\"addbook:add\"><INPUT TYPE=hidden name=vcard VALUE=\"%s\"><INPUT type=submit value=\"%s\"></INPUT></FORM>", 
  928.             vEscCard, XP_GetString(MK_MSG_ADD_TO_ADDR_BOOK));
  929.     }
  930.     else 
  931.     {
  932.         htmlLine1 = PR_smprintf ("<FORM name=form1><INPUT type=reset value=\\\"%s\\\" onClick=\\\"showBasic%d();\\\"></INPUT></FORM>", 
  933.             XP_GetString(MK_ADDR_VIEW_CONDENSED_VCARD), unique);
  934.  
  935.         htmlLine2 = PR_smprintf ("<FORM name=form1 METHOD=get ACTION=\"addbook:add\"><INPUT TYPE=hidden name=vcard VALUE=\"%s\"><INPUT type=submit value=\"%s\"></INPUT></FORM>",
  936.             vEscCard, XP_GetString(MK_MSG_ADD_TO_ADDR_BOOK));
  937.     }
  938.  
  939.     if (!htmlLine1 && !htmlLine2)
  940.     {
  941.         XP_FREEIF (vEscCard);
  942.         XP_FREEIF (htmlLine1);
  943.         XP_FREEIF (htmlLine2);
  944.         return MK_OUT_OF_MEMORY;
  945.     }
  946.     
  947.     status = OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  948.     if (status < 0) goto FAIL;
  949.     status = WriteEachLineToStream (obj, "<SCRIPT>document.write(\"");
  950.     if (status < 0) goto FAIL;
  951.     status = WriteLineToStream (obj, htmlLine1);
  952.     if (status < 0) goto FAIL;
  953.     status = WriteEachLineToStream (obj, "\")</SCRIPT>");
  954.     if (status < 0) goto FAIL;
  955.     status = WriteLineToStream (obj, htmlLine2);
  956.     if (status < 0) goto FAIL;
  957.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  958.     if (status < 0) goto FAIL;
  959.  
  960.     FAIL:
  961.     XP_FREEIF (vEscCard);
  962.     XP_FREEIF (htmlLine1);
  963.     XP_FREEIF (htmlLine2);
  964.  
  965.     return status;
  966. }
  967.  
  968. static int BeginLayer(MimeObject *obj, XP_Bool basic)
  969. {
  970.     int status = 0;
  971.     char * captionLine = NULL;
  972.  
  973.     if (basic)
  974.     {
  975.         captionLine = PR_smprintf ("<LAYER NAME=basic%d>", unique);
  976.     }
  977.     else
  978.     {
  979.         captionLine = PR_smprintf ("<ILAYER NAME=advanced%d VISIBILITY=\"hide\">", unique);
  980.     }
  981.  
  982.     if (captionLine)
  983.     {
  984.         status = WriteEachLineToStream (obj, captionLine);
  985.         XP_FREE(captionLine);
  986.         if (status < 0) return status;
  987.         status = OutputTable (obj, FALSE, FALSE, NULL, NULL, NULL);
  988.         if (status < 0) return status;
  989.         status = OutputTableRowOrData (obj, TRUE, FALSE, NULL, NULL, NULL, NULL);
  990.         if (status < 0) return status;
  991.         status = OutputTableRowOrData (obj, FALSE, FALSE, NULL, "TOP", NULL, NULL);
  992.         if (status < 0) return status;
  993.         status = OutputTable (obj, FALSE, TRUE, "0", "0", "#FFFFFF");
  994.         if (status < 0) return status;
  995.         if (basic)
  996.         {
  997.             status = OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  998.             if (status < 0) return status;
  999.             status = OutputTableRowOrData(obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  1000.             if (status < 0) return status;
  1001.         }
  1002.         else
  1003.         {
  1004.             status = OutputTableRowOrData(obj, TRUE, FALSE, NULL, NULL, NULL, NULL);
  1005.             if (status < 0) return status;
  1006.             status = OutputTableRowOrData(obj, FALSE, FALSE, NULL, NULL, NULL, NULL);
  1007.             if (status < 0) return status;
  1008.         }
  1009.  
  1010.         status = OutputTable (obj, FALSE, FALSE, "4", NULL, NULL);
  1011.         if (status < 0) return status;
  1012.         status = OutputTableRowOrData (obj, TRUE, FALSE, NULL, NULL, NULL, NULL);
  1013.         if (status < 0) return status;
  1014.         status = OutputTableRowOrData (obj, FALSE, FALSE, NULL, NULL, NULL, NULL);
  1015.         if (status < 0) return status;
  1016.     }
  1017.     else
  1018.         status = MK_OUT_OF_MEMORY;
  1019.  
  1020.     return status;
  1021. }
  1022.  
  1023. static int EndLayer(MimeObject *obj, XP_Bool basic, VObject* v)
  1024. {
  1025.     int status = 0;
  1026.     char * captionLine = NULL;
  1027.  
  1028.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1029.     if (status < 0) return status;
  1030.     status = OutputTableRowOrData (obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  1031.     if (status < 0) return status;
  1032.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  1033.     if (status < 0) return status;
  1034.  
  1035.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1036.     if (status < 0) return status;
  1037.     status = OutputTableRowOrData (obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  1038.     if (status < 0) return status;
  1039.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  1040.     if (status < 0) return status;
  1041.     status = OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1042.     if (status < 0) return status;
  1043.  
  1044.     status = OutputButtons(obj, basic, v);
  1045.     if (status < 0) return status;
  1046.  
  1047.     status = OutputTableRowOrData (obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  1048.     if (status < 0) return status;
  1049.     status = OutputTable (obj, TRUE, FALSE, NULL, NULL, NULL);
  1050.     if (status < 0) return status;
  1051.  
  1052.     if (!basic) 
  1053.     {
  1054.         status = WriteEachLineToStream (obj, "</ILAYER>");
  1055.         if (status < 0) return status;
  1056.         status = WriteEachLineToStream (obj, "<P><SCRIPT>");
  1057.         if (status < 0) return status;
  1058.         captionLine = PR_smprintf ("function showAdvanced%d() {", unique);
  1059.         if (captionLine)
  1060.             status = WriteEachLineToStream (obj, captionLine);
  1061.         XP_FREEIF (captionLine);
  1062.         captionLine = NULL;
  1063.         if (status < 0) return status;
  1064.         captionLine = PR_smprintf ("document.layers[\"basic%d\"].visibility = \"hide\";", unique);
  1065.         if (captionLine)
  1066.             status = WriteEachLineToStream (obj, captionLine);
  1067.         XP_FREEIF (captionLine);
  1068.         captionLine = NULL;
  1069.         if (status < 0) return status;
  1070.         captionLine = PR_smprintf ("document.layers[\"advanced%d\"].visibility = \"inherit\";", unique);
  1071.         if (captionLine)
  1072.             status = WriteEachLineToStream (obj, captionLine);
  1073.         XP_FREEIF (captionLine);
  1074.         captionLine = NULL;
  1075.         if (status < 0) return status;
  1076.         status = WriteEachLineToStream (obj, "};");
  1077.         if (status < 0) return status;
  1078.         captionLine = PR_smprintf ("function showBasic%d() {", unique);
  1079.         if (captionLine)
  1080.             status = WriteEachLineToStream (obj, captionLine);
  1081.         XP_FREEIF (captionLine);
  1082.         captionLine = NULL;
  1083.         if (status < 0) return status;
  1084.         captionLine = PR_smprintf ("document.layers[\"advanced%d\"].visibility = \"hide\";", unique);
  1085.         if (captionLine)
  1086.             status = WriteEachLineToStream (obj, captionLine);
  1087.         if (status < 0) return status;
  1088.         captionLine = PR_smprintf ("document.layers[\"basic%d\"].visibility = \"inherit\";", unique);
  1089.         if (captionLine)
  1090.             status = WriteEachLineToStream (obj, captionLine);
  1091.         XP_FREEIF (captionLine);
  1092.         if (status < 0) return status;
  1093.         status = WriteEachLineToStream (obj, "}; </SCRIPT></P>");
  1094.     } 
  1095.     else {
  1096.         status = WriteEachLineToStream (obj, "</LAYER>");
  1097.     }
  1098.  
  1099.     if (status < 0) return status;
  1100.     return 0;
  1101. }
  1102.  
  1103. static int EndVCard (MimeObject *obj)
  1104. {
  1105.     int status = 0;
  1106.  
  1107.     /* Scribble HTML-ending stuff into the stream */
  1108.     char htmlFooters[32];
  1109.     PR_snprintf (htmlFooters, sizeof(htmlFooters), "</BODY>%s</HTML>%s", LINEBREAK, LINEBREAK);
  1110.     status = MimeObject_write(obj, htmlFooters, XP_STRLEN(htmlFooters), FALSE);
  1111.  
  1112.     if (status < 0) return status;
  1113.  
  1114.     if (obj->options && obj->options->set_html_state_fn) {
  1115.         status = obj->options->set_html_state_fn(obj->options->stream_closure,
  1116.                                                  TRUE,   /* layer_encapulate_p */
  1117.                                                  FALSE,  /* start_p */
  1118.                                                  FALSE); /* abort_p */
  1119.         if (status < 0) return status;
  1120.     }
  1121.     
  1122.     return 0;
  1123. }
  1124.  
  1125. static int BeginVCard (MimeObject *obj)
  1126. {
  1127.     int status = 0;
  1128.  
  1129.     /* Scribble HTML-starting stuff into the stream */
  1130.     char htmlHeaders[32];
  1131.  
  1132.     if (obj->options && obj->options->set_html_state_fn) {
  1133.         status = obj->options->set_html_state_fn(obj->options->stream_closure,
  1134.                                                  TRUE,   /* layer_encapulate_p */
  1135.                                                  TRUE,   /* start_p */
  1136.                                                  FALSE); /* abort_p */
  1137.         if (status < 0) return status;
  1138.     }
  1139.     
  1140.     unique++;
  1141.     PR_snprintf (htmlHeaders, sizeof(htmlHeaders), "<HTML>%s<BODY>%s", LINEBREAK, LINEBREAK);
  1142.     status = MimeObject_write(obj, htmlHeaders, XP_STRLEN(htmlHeaders), TRUE);
  1143.  
  1144.     if (status < 0) return status;
  1145.  
  1146.     return 0;
  1147. }
  1148.  
  1149. static int WriteOutVCard (MimeObject *obj, VObject* v)
  1150. {
  1151.     int status = 0;
  1152.  
  1153.     status = BeginVCard (obj);
  1154.     if (status < 0) return status;
  1155.     
  1156.     /* write out basic layer */
  1157.     status = BeginLayer(obj, TRUE);
  1158.     if (status < 0) return status;
  1159.     status = OutputBasicVcard(obj, v);
  1160.     if (status < 0) return status;
  1161.     status = EndLayer(obj, TRUE, v);
  1162.     if (status < 0) return status;
  1163.  
  1164.     /* write out advanced layer */
  1165.     status = BeginLayer(obj, FALSE);
  1166.     if (status < 0) return status;
  1167.     status = OutputAdvancedVcard(obj, v);
  1168.     if (status < 0) return status;
  1169.     status = EndLayer(obj, FALSE, v);
  1170.     if (status < 0) return status;
  1171.  
  1172.     status = EndVCard (obj);
  1173.     if (status < 0) return status;
  1174.  
  1175.     return 0;
  1176. }
  1177.  
  1178. static void GetAddressProperties (VObject* o, char ** attribName)
  1179. {
  1180.     VObject* domProp = isAPropertyOf(o, VCDomesticProp);
  1181.     VObject* intlProp = isAPropertyOf(o, VCInternationalProp);
  1182.     VObject* postal = isAPropertyOf(o, VCPostalProp);
  1183.     VObject* parcel = isAPropertyOf(o, VCParcelProp);
  1184.     VObject* home = isAPropertyOf(o, VCHomeProp);
  1185.     VObject* work = isAPropertyOf(o, VCWorkProp);
  1186.     if (domProp) {
  1187.         StrAllocCat ((*attribName), " ");
  1188.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_DOM_TYPE));
  1189.     }
  1190.     if (intlProp) {
  1191.         StrAllocCat ((*attribName), " ");
  1192.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_INTL_TYPE));
  1193.     }
  1194.     if (postal) {
  1195.         StrAllocCat ((*attribName), " ");
  1196.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_POSTAL_TYPE));
  1197.     }
  1198.     if (parcel) {
  1199.         StrAllocCat ((*attribName), " ");
  1200.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_PARCEL_TYPE));
  1201.     }
  1202.     if (home) {
  1203.         StrAllocCat ((*attribName), " ");
  1204.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_HOME_TYPE));
  1205.     }
  1206.     if (work) {
  1207.         StrAllocCat ((*attribName), " ");
  1208.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_WORK_TYPE));
  1209.     }
  1210. }
  1211.  
  1212.  
  1213. static void GetTelephoneProperties (VObject* o, char ** attribName)
  1214. {
  1215.     VObject* prefProp = isAPropertyOf(o, VCPreferredProp);
  1216.     VObject* home = isAPropertyOf(o, VCHomeProp);
  1217.     VObject* work = isAPropertyOf(o, VCWorkProp);
  1218.     VObject* voiceProp = isAPropertyOf(o, VCVoiceProp);
  1219.     VObject* fax = isAPropertyOf(o, VCFaxProp);
  1220.     VObject* msg = isAPropertyOf(o, VCMessageProp);
  1221.     VObject* cell = isAPropertyOf(o, VCCellularProp);
  1222.     VObject* pager = isAPropertyOf(o, VCPagerProp);
  1223.     VObject* bbs = isAPropertyOf(o, VCBBSProp);
  1224.     if (prefProp) {
  1225.         StrAllocCat ((*attribName), " ");
  1226.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_PREF_TYPE));
  1227.     }
  1228.     if (home) {
  1229.         StrAllocCat ((*attribName), " ");
  1230.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_HOME_TYPE));
  1231.     }
  1232.     if (work) {
  1233.         StrAllocCat ((*attribName), " ");
  1234.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_WORK_TYPE));
  1235.     }
  1236.     if (voiceProp) {
  1237.         StrAllocCat ((*attribName), " ");
  1238.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_VOICE_TYPE));
  1239.     }
  1240.     if (fax) {
  1241.         StrAllocCat ((*attribName), " ");
  1242.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_FAX_TYPE));
  1243.     }
  1244.     if (msg) {
  1245.         StrAllocCat ((*attribName), " ");
  1246.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_MSG_TYPE));
  1247.     }
  1248.     if (cell) {
  1249.         StrAllocCat ((*attribName), " ");
  1250.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_CELL_TYPE));
  1251.     }
  1252.     if (pager) {
  1253.         StrAllocCat ((*attribName), " ");
  1254.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_PAGER_TYPE));
  1255.     }
  1256.     if (bbs) {
  1257.         StrAllocCat ((*attribName), " ");
  1258.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_BBS_TYPE));
  1259.     }
  1260. }
  1261.  
  1262. static void GetEmailProperties (VObject* o, char ** attribName)
  1263. {
  1264.     
  1265.     VObject* prefProp = isAPropertyOf(o, VCPreferredProp);
  1266.     VObject* home = isAPropertyOf(o, VCHomeProp);
  1267.     VObject* work = isAPropertyOf(o, VCWorkProp);
  1268.     VObject* aol = isAPropertyOf(o, VCAOLProp);
  1269.     VObject* applelink = isAPropertyOf(o, VCAppleLinkProp);
  1270.     VObject* att = isAPropertyOf(o, VCATTMailProp);
  1271.     VObject* cis = isAPropertyOf(o, VCCISProp);
  1272.     VObject* eworld = isAPropertyOf(o, VCEWorldProp);
  1273.     VObject* internet = isAPropertyOf(o, VCInternetProp);
  1274.     VObject* ibmmail = isAPropertyOf(o, VCIBMMailProp);
  1275.     VObject* mcimail = isAPropertyOf(o, VCMCIMailProp);
  1276.     VObject* powershare = isAPropertyOf(o, VCPowerShareProp);
  1277.     VObject* prodigy = isAPropertyOf(o, VCProdigyProp);
  1278.     VObject* telex = isAPropertyOf(o, VCTLXProp);
  1279.     VObject* x400 = isAPropertyOf(o, VCX400Prop);
  1280.     if (prefProp) {
  1281.         StrAllocCat ((*attribName), " ");
  1282.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_PREF_TYPE));
  1283.     }
  1284.     if (home) {
  1285.         StrAllocCat ((*attribName), " ");
  1286.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_HOME_TYPE));
  1287.     }
  1288.     if (work) {
  1289.         StrAllocCat ((*attribName), " ");
  1290.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_WORK_TYPE));
  1291.     }
  1292.     if (aol) {
  1293.         StrAllocCat ((*attribName), " ");
  1294.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_AOL_TYPE));
  1295.     }
  1296.     if (applelink) {
  1297.         StrAllocCat ((*attribName), " ");
  1298.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_APPLELINK_TYPE));
  1299.     }
  1300.     if (att) {
  1301.         StrAllocCat ((*attribName), " ");
  1302.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_ATTMAIL_TYPE));
  1303.     }
  1304.     if (cis) {
  1305.         StrAllocCat ((*attribName), " ");
  1306.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_CSI_TYPE));
  1307.     }
  1308.     if (eworld) {
  1309.         StrAllocCat ((*attribName), " ");
  1310.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_EWORLD_TYPE));
  1311.     }
  1312.     if (internet) {
  1313.         StrAllocCat ((*attribName), " ");
  1314.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_INTERNET_TYPE));
  1315.     }
  1316.     if (ibmmail) {
  1317.         StrAllocCat ((*attribName), " ");
  1318.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_IBMMAIL_TYPE));
  1319.     }
  1320.     if (mcimail) {
  1321.         StrAllocCat ((*attribName), " ");
  1322.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_MCIMAIL_TYPE));
  1323.     }
  1324.     if (powershare) {
  1325.         StrAllocCat ((*attribName), " ");
  1326.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_POWERSHARE_TYPE));
  1327.     }
  1328.     if (prodigy) {
  1329.         StrAllocCat ((*attribName), " ");
  1330.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_PRODIGY_TYPE));
  1331.     }
  1332.     if (telex) {
  1333.         StrAllocCat ((*attribName), " ");
  1334.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_TLX_TYPE));
  1335.     }
  1336.     if (x400) {
  1337.         StrAllocCat ((*attribName), " ");
  1338.         StrAllocCat ((*attribName), XP_GetString (MK_LDAP_X400));
  1339.     }
  1340.  
  1341. }
  1342.  
  1343. static int WriteOutEachVCardPhoneProperty (MimeObject *obj, VObject* o)
  1344. {
  1345.     char *attribName = NULL;
  1346.     char *value = NULL;
  1347.     int status = 0;
  1348.  
  1349.     if (vObjectName(o)) 
  1350.     {
  1351.         if (strcasecomp (VCTelephoneProp, vObjectName(o)) == 0) 
  1352.         {
  1353.             if (VALUE_TYPE(o)) 
  1354.             {
  1355.                 GetTelephoneProperties(o, &attribName);
  1356.                 if (!attribName)
  1357.                     attribName = XP_STRDUP (XP_GetString (MK_LDAP_PHONE_NUMBER));
  1358.                 attribName = StrAllocCat(attribName, ": ");
  1359.                 value = fakeCString (vObjectUStringZValue(o));
  1360.                 if (value)
  1361.                 {
  1362.                     attribName = StrAllocCat (attribName, value);
  1363.                     XP_FREEIF (value);
  1364.                     if (attribName)
  1365.                     {
  1366.                         status = OutputFont(obj, FALSE, "-1", NULL);
  1367.                         if (status < 0) {
  1368.                             XP_FREEIF (attribName);
  1369.                             return status;
  1370.                         }
  1371.                         status = WriteLineToStream (obj, attribName);
  1372.                         if (status < 0) {
  1373.                             XP_FREEIF (attribName);
  1374.                             return status;
  1375.                         }
  1376.                         status = OutputFont(obj, TRUE, NULL, NULL);
  1377.                         if (status < 0) {
  1378.                             XP_FREEIF (attribName);
  1379.                             return status;
  1380.                         }
  1381.                     }
  1382.                     XP_FREEIF (attribName);
  1383.                 }
  1384.             }
  1385.         }
  1386.     }
  1387.     return status;
  1388. }
  1389.  
  1390. static int WriteOutVCardPhoneProperties (MimeObject *obj, VObject* v)
  1391. {
  1392.     int status = 0;
  1393.     VObjectIterator t;
  1394.     VObject *eachProp;
  1395.  
  1396.     WriteOutEachVCardPhoneProperty (obj, v);
  1397.     initPropIterator(&t,v);
  1398.     while (moreIteration(&t) && status >= 0)
  1399.     {
  1400.         eachProp = nextVObject(&t);
  1401.         status = WriteOutEachVCardPhoneProperty (obj, eachProp);
  1402.     }
  1403.  
  1404.     if (status < 0) return status;
  1405.  
  1406.     return 0;
  1407. }
  1408.  
  1409. static int WriteOutEachVCardProperty (MimeObject *obj, VObject* o, int* numEmail)
  1410. {
  1411.     char *attribName = NULL;
  1412.     char * url = NULL;
  1413.     char *value = NULL;
  1414.     char *ptr = NULL;
  1415.     int status = 0;
  1416.  
  1417.     if (vObjectName(o)) {
  1418.  
  1419.         if (strcasecomp (VCPhotoProp, vObjectName(o)) == 0) {
  1420.             VObject* urlProp = isAPropertyOf(o, VCURLProp);
  1421.             if (urlProp) {
  1422.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_PHOTOGRAPH));
  1423.                 /* format the value string to the url */
  1424.                 value = fakeCString (vObjectUStringZValue(o));
  1425.                 if (value)
  1426.                     url = PR_smprintf ("<IMG SRC = ""%s""", value);
  1427.                 XP_FREEIF (value);
  1428.                 value = NULL;
  1429.                 goto DOWRITE;
  1430.             }
  1431.         }
  1432.  
  1433.         if (strcasecomp (VCBirthDateProp, vObjectName(o)) == 0) {
  1434.             if (VALUE_TYPE(o)) {
  1435.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_BIRTHDAY));
  1436.                 value = fakeCString (vObjectUStringZValue(o));
  1437.                 goto DOWRITE;
  1438.             }
  1439.         }
  1440.  
  1441.         if (strcasecomp (VCDeliveryLabelProp, vObjectName(o)) == 0) {
  1442.             attribName = XP_STRDUP (XP_GetString (MK_LDAP_LABEL));
  1443.             GetAddressProperties(o, &attribName);
  1444.             value = fakeCString (vObjectUStringZValue(o));
  1445.             goto DOWRITE;
  1446.         }
  1447.  
  1448.         if (strcasecomp (VCEmailAddressProp, vObjectName(o)) == 0) {
  1449.             if ((*numEmail) != 1)
  1450.             {
  1451.                 if (VALUE_TYPE(o)) {
  1452.                     (*numEmail)++;
  1453.                     attribName = XP_STRDUP (XP_GetString (MK_LDAP_EMAIL_ADDRESS));
  1454.                     GetEmailProperties(o, &attribName);
  1455.                     value = fakeCString (vObjectUStringZValue(o));
  1456.                     goto DOWRITE;
  1457.                 };
  1458.             }
  1459.         }
  1460.  
  1461.         if (strcasecomp (VCFamilyNameProp, vObjectName(o)) == 0) {
  1462.             if (VALUE_TYPE(o)) {
  1463.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_SURNAME));
  1464.                 value = fakeCString (vObjectUStringZValue(o));
  1465.                 goto DOWRITE;
  1466.             }
  1467.         }
  1468.  
  1469.         if (strcasecomp (VCGivenNameProp, vObjectName(o)) == 0) {
  1470.             if (VALUE_TYPE(o)) {
  1471.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_GIVEN_NAME));
  1472.                 value = fakeCString (vObjectUStringZValue(o));
  1473.                 goto DOWRITE;
  1474.             }
  1475.         }
  1476.  
  1477.         if (strcasecomp (VCNamePrefixesProp, vObjectName(o)) == 0) {
  1478.             if (VALUE_TYPE(o)) {
  1479.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_NAME_PREFIX));
  1480.                 value = fakeCString (vObjectUStringZValue(o));
  1481.                 goto DOWRITE;
  1482.             }
  1483.         }
  1484.  
  1485.         if (strcasecomp (VCNameSuffixesProp, vObjectName(o)) == 0) {
  1486.             if (VALUE_TYPE(o)) {
  1487.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_NAME_SUFFIX));
  1488.                 value = fakeCString (vObjectUStringZValue(o));
  1489.                 goto DOWRITE;
  1490.             }
  1491.         }
  1492.  
  1493.         if (strcasecomp (VCAdditionalNamesProp, vObjectName(o)) == 0) {
  1494.             if (VALUE_TYPE(o)) {
  1495.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_MIDDLE_NAME));
  1496.                 value = fakeCString (vObjectUStringZValue(o));
  1497.                 goto DOWRITE;
  1498.             }
  1499.         }
  1500.  
  1501.         if (strcasecomp (VCMailerProp, vObjectName(o)) == 0) {
  1502.             if (VALUE_TYPE(o)) {
  1503.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_MAILER));
  1504.                 value = fakeCString (vObjectUStringZValue(o));
  1505.                 goto DOWRITE;
  1506.             }
  1507.         }
  1508.  
  1509.         if (strcasecomp (VCTimeZoneProp, vObjectName(o)) == 0) {
  1510.             if (VALUE_TYPE(o)) {
  1511.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_TZ));
  1512.                 value = fakeCString (vObjectUStringZValue(o));
  1513.                 goto DOWRITE;
  1514.             }
  1515.         }
  1516.  
  1517.         if (strcasecomp (VCGeoProp, vObjectName(o)) == 0) {
  1518.             if (VALUE_TYPE(o)) {
  1519.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_GEO));
  1520.                 value = fakeCString (vObjectUStringZValue(o));
  1521.                 goto DOWRITE;
  1522.             }
  1523.         }
  1524.  
  1525.         if (strcasecomp (VCBusinessRoleProp, vObjectName(o)) == 0) {
  1526.             if (VALUE_TYPE(o)) {
  1527.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_ROLE));
  1528.                 value = fakeCString (vObjectUStringZValue(o));
  1529.                 goto DOWRITE;
  1530.             }
  1531.         }
  1532.  
  1533.         if (strcasecomp (VCLogoProp, vObjectName(o)) == 0) {
  1534.             VObject* urlProp = isAPropertyOf(o, VCURLProp);
  1535.             if (urlProp) {
  1536.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_LOGO));
  1537.                 /* format the value string to the url */
  1538.                 value = fakeCString (vObjectUStringZValue(o));
  1539.                 if (value)
  1540.                     url = PR_smprintf ("<IMG SRC = ""%s""", value);
  1541.                 XP_FREEIF (value);
  1542.                 goto DOWRITE;
  1543.             }
  1544.         }
  1545.  
  1546.         if (strcasecomp (VCAgentProp, vObjectName(o)) == 0) {
  1547.             attribName = XP_STRDUP (XP_GetString (MK_LDAP_SECRETARY));
  1548.             goto DOWRITE;
  1549.         }
  1550.  
  1551.         if (strcasecomp (VCLastRevisedProp, vObjectName(o)) == 0) {
  1552.             if (VALUE_TYPE(o)) {
  1553.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_REVISION));
  1554.                 value = fakeCString (vObjectUStringZValue(o));
  1555.                 goto DOWRITE;
  1556.             }
  1557.         }
  1558.  
  1559.         if (strcasecomp (VCPronunciationProp, vObjectName(o)) == 0) {
  1560.             if (VALUE_TYPE(o)) {
  1561.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_SOUND));
  1562.                 value = fakeCString (vObjectUStringZValue(o));
  1563.                 goto DOWRITE;
  1564.             }
  1565.         }
  1566.  
  1567.  
  1568.         if (strcasecomp (VCVersionProp, vObjectName(o)) == 0) {
  1569.             if (VALUE_TYPE(o)) {
  1570.                 attribName = XP_STRDUP (XP_GetString (MK_LDAP_VERSION));
  1571.                 value = fakeCString (vObjectUStringZValue(o));
  1572.                 goto DOWRITE;
  1573.             }
  1574.         }
  1575.  
  1576.         if (!attribName) 
  1577.             return 0;
  1578.     
  1579.     DOWRITE:
  1580.         OutputTableRowOrData(obj, TRUE, FALSE, "LEFT", "TOP", NULL, NULL);
  1581.         OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  1582.         if (attribName) { 
  1583.             OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  1584.             status = WriteAttribute (obj, attribName);
  1585.             XP_FREE (attribName);
  1586.             OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1587.         }
  1588.  
  1589.         if (value) {
  1590.             OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  1591.             status = WriteValue (obj, value);
  1592.             XP_FREE (value);
  1593.             OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1594.         }
  1595.  
  1596.         if (url) {
  1597.             OutputTableRowOrData (obj, FALSE, FALSE, "LEFT", "TOP", NULL, NULL);
  1598.             status = WriteValue (obj, url);
  1599.             XP_FREE (url);
  1600.             OutputTableRowOrData (obj, FALSE, TRUE, NULL, NULL, NULL, NULL);
  1601.         }
  1602.         OutputTableRowOrData(obj, TRUE, TRUE, NULL, NULL, NULL, NULL);
  1603.     }
  1604.  
  1605.     if (status < 0) return status;
  1606.  
  1607.     return 0;
  1608. }
  1609.  
  1610.  
  1611. static int WriteOutVCardProperties (MimeObject *obj, VObject* v, int* numEmail)
  1612. {
  1613.     int status = 0;
  1614.     VObjectIterator t;
  1615.     VObject *eachProp;
  1616.  
  1617.     WriteOutEachVCardProperty (obj, v, numEmail);
  1618.     initPropIterator(&t,v);
  1619.     while (moreIteration(&t) && status >= 0)
  1620.     {
  1621.         eachProp = nextVObject(&t);
  1622.         status = WriteOutVCardProperties (obj, eachProp, numEmail);
  1623.     }
  1624.  
  1625.     if (status < 0) return status;
  1626.  
  1627.     return 0;
  1628. }
  1629.  
  1630. static int WriteLineToStream (MimeObject *obj, const char *line)
  1631. {
  1632.     int status = 0;
  1633.     char *htmlLine;
  1634.     int htmlLen = XP_STRLEN(line) + XP_STRLEN("<DT></DT>") + 1;;
  1635.  
  1636.     htmlLine = (char *) XP_ALLOC (htmlLen);
  1637.     if (htmlLine)
  1638.     {
  1639.         htmlLine[0] = '\0';
  1640.         XP_STRCAT (htmlLine, "<DT>");
  1641.         XP_STRCAT (htmlLine, line);
  1642.         XP_STRCAT (htmlLine, "</DT>");
  1643.         status = MimeObject_write(obj, htmlLine, XP_STRLEN(htmlLine), TRUE);
  1644. #ifdef DEBUG_mwatkins
  1645.         if (XP_STRLEN (htmlLine) < 500)
  1646.             XP_Trace("%s%c", htmlLine, '\n');
  1647. #endif
  1648.         XP_FREE ((void*) htmlLine);
  1649.     }
  1650.     else
  1651.         status = MK_OUT_OF_MEMORY;
  1652.  
  1653.     return status;
  1654. }
  1655.  
  1656. static int WriteAttribute (MimeObject *obj, const char *attrib)
  1657. {
  1658.     int status = 0;
  1659.     OutputFont(obj, FALSE, "-1", NULL);
  1660.     status  = WriteLineToStream (obj, attrib);
  1661.     OutputFont(obj, TRUE, NULL, NULL);
  1662.     return status;
  1663. }
  1664.  
  1665.  
  1666. static int WriteValue (MimeObject *obj, const char *value)
  1667. {
  1668.     int status = 0;
  1669.     OutputFont(obj, FALSE, "-1", NULL);
  1670.     status  = WriteLineToStream (obj, value);
  1671.     OutputFont(obj, TRUE, NULL, NULL);
  1672.     return status;
  1673. }
  1674.  
  1675.  
  1676.