/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include "e-mail-parser-tnef-attachment.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef HAVE_YTNEF_H
#include
#elif defined HAVE_LIBYTNEF_YTNEF_H
#include
#endif
#include
#include
#include
#define d(x)
typedef struct _EMailParserTnefAttachment {
EExtension parent;
GSettings *settings;
gint mode;
gboolean show_suppressed;
} EMailParserTnefAttachment;
typedef struct _EMailParserTnefAttachmentClass {
EExtensionClass parent_class;
} EMailParserTnefAttachmentClass;
GType e_mail_parser_tnef_attachment_get_type (void);
static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (
EMailParserTnefAttachment,
e_mail_parser_tnef_attachment,
E_TYPE_EXTENSION,
0,
G_IMPLEMENT_INTERFACE_DYNAMIC (
E_TYPE_MAIL_EXTENSION,
e_mail_parser_mail_extension_interface_init)
G_IMPLEMENT_INTERFACE_DYNAMIC (
E_TYPE_MAIL_PARSER_EXTENSION,
e_mail_parser_parser_extension_interface_init));
static const gchar* parser_mime_types[] = { "application/vnd.ms-tnef",
"application/ms-tnefl",
NULL };
gint verbose = 0;
gint saveRTF = 0;
gint saveintermediate = 0;
gboolean loaded = FALSE;
void processTnef (TNEFStruct *tnef, const gchar *tmpdir);
void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir);
void saveVCard (TNEFStruct *tnef, const gchar *tmpdir);
void saveVTask (TNEFStruct *tnef, const gchar *tmpdir);
/* Other Prototypes */
void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]);
void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]);
void quotedfprint (FILE *fptr, variableLength *vl);
void cstylefprint (FILE *fptr, variableLength *vl);
void printRtf (FILE *fptr, variableLength *vl);
void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef);
guchar getRruleCount (guchar a, guchar b);
guchar getRruleMonthNum (guchar a, guchar b);
gchar * getRruleDayname (guchar a);
static gchar *
sanitize_filename (const gchar *filename)
{
gchar * sanitized_name;
sanitized_name = g_path_get_basename (filename);
if (sanitized_name == NULL || !g_strcmp0 (sanitized_name, ".")) {
g_free (sanitized_name);
return NULL;
} else {
return g_strdelimit (sanitized_name, " ", '_');
}
}
static GSList *
empe_tnef_attachment_parse (EMailParserExtension *extension,
EMailParser *parser,
CamelMimePart *part,
GString *part_id,
GCancellable *cancellable)
{
gchar *tmpdir, *name;
CamelStream *out;
struct dirent *d;
DIR *dir;
CamelMultipart *mp;
CamelMimePart *mainpart;
CamelDataWrapper *content;
gint len;
TNEFStruct tnef;
GSList *parts;
tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
if (tmpdir == NULL)
return NULL;
name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL);
out = camel_stream_fs_new_with_name (name, O_RDWR | O_CREAT, 0666, NULL);
if (out == NULL) {
g_free (name);
return NULL;
}
content = camel_medium_get_content ((CamelMedium *) part);
if (content == NULL) {
g_free (name);
g_object_unref (out);
return NULL;
}
if (camel_data_wrapper_decode_to_stream_sync (content, out, NULL, NULL) == -1
|| camel_stream_close (out, NULL, NULL) == -1) {
g_object_unref (out);
g_free (name);
return NULL;
}
g_object_unref (out);
/* Extracting the winmail.dat */
TNEFInitialize (&tnef);
tnef.Debug = verbose;
if (TNEFParseFile (name, &tnef) == -1) {
printf("ERROR processing file\n");
}
processTnef (&tnef, tmpdir);
TNEFFree (&tnef);
/* Extraction done */
dir = opendir (tmpdir);
if (dir == NULL) {
g_object_unref (out);
g_free (name);
return NULL;
}
mainpart = camel_mime_part_new ();
mp = camel_multipart_new ();
camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed");
camel_multipart_set_boundary (mp, NULL);
camel_medium_set_content ((CamelMedium *) mainpart, (CamelDataWrapper *) mp);
while ((d = readdir (dir))) {
CamelMimePart *part;
CamelDataWrapper *content;
CamelStream *stream;
gchar *path;
const gchar *type;
if (!strcmp(d->d_name, ".")
|| !strcmp(d->d_name, "..")
|| !strcmp(d->d_name, ".evo-attachment.tnef"))
continue;
path = g_build_filename (tmpdir, d->d_name, NULL);
stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0, NULL);
content = camel_data_wrapper_new ();
camel_data_wrapper_construct_from_stream_sync (
content, stream, NULL, NULL);
g_object_unref (stream);
part = camel_mime_part_new ();
camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BINARY);
camel_medium_set_content ((CamelMedium *) part, content);
g_object_unref (content);
type = e_mail_part_snoop_type (part);
if (type)
camel_data_wrapper_set_mime_type ((CamelDataWrapper *) part, type);
camel_mime_part_set_filename (part, d->d_name);
g_free (path);
camel_multipart_add_part (mp, part);
g_object_unref (part);
}
closedir (dir);
len = part_id->len;
g_string_append_printf(part_id, ".tnef");
parts = NULL;
if (camel_multipart_get_number (mp) > 0) {
CamelMimePart *part = camel_mime_part_new ();
camel_medium_set_content ((CamelMedium *) part,
CAMEL_DATA_WRAPPER (mp));
parts = e_mail_parser_parse_part_as (parser, part,
part_id, "multipart/mixed", cancellable);
g_object_unref (part);
}
g_string_truncate (part_id, len);
if (parts) {
parts = e_mail_parser_wrap_as_attachment (parser,
part, parts, part_id, cancellable);
}
g_object_unref (mp);
g_object_unref (mainpart);
g_free (name);
g_free (tmpdir);
return parts;
}
static const gchar **
empe_mime_types (EMailExtension *extension)
{
return parser_mime_types;
}
void
e_mail_parser_tnef_attachment_type_register (GTypeModule *type_module)
{
e_mail_parser_tnef_attachment_register_type (type_module);
}
static void
e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
{
iface->mime_types = empe_mime_types;
}
static void
e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
{
iface->parse = empe_tnef_attachment_parse;
}
static void
e_mail_parser_tnef_attachment_constructed (GObject *object)
{
EExtensible *extensible;
EMailExtensionRegistry *reg;
extensible = e_extension_get_extensible (E_EXTENSION (object));
reg = E_MAIL_EXTENSION_REGISTRY (extensible);
e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
}
static void
e_mail_parser_tnef_attachment_class_init (EMailParserTnefAttachmentClass *class)
{
GObjectClass *object_class;
EExtensionClass *extension_class;
object_class = G_OBJECT_CLASS (class);
object_class->constructed = e_mail_parser_tnef_attachment_constructed;
extension_class = E_EXTENSION_CLASS (class);
extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
}
void
e_mail_parser_tnef_attachment_class_finalize (EMailParserTnefAttachmentClass *class)
{
}
static void
e_mail_parser_tnef_attachment_init (EMailParserTnefAttachment *parser)
{
}
void
processTnef (TNEFStruct *tnef,
const gchar *tmpdir)
{
variableLength *filename;
variableLength *filedata;
Attachment *p;
gint RealAttachment;
gint object;
gchar *ifilename = NULL;
gchar *absfilename, *file;
gint count;
gint foundCal = 0;
FILE *fptr;
/* First see if this requires special processing. */
/* ie: it's a Contact Card, Task, or Meeting request (vCal/vCard) */
if (tnef->messageClass[0] != 0) {
if (strcmp(tnef->messageClass, "IPM.Contact") == 0) {
saveVCard (tnef, tmpdir);
}
if (strcmp(tnef->messageClass, "IPM.Task") == 0) {
saveVTask (tnef, tmpdir);
}
if (strcmp(tnef->messageClass, "IPM.Appointment") == 0) {
saveVCalendar (tnef, tmpdir);
foundCal = 1;
}
}
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8,0x24))) != MAPI_UNDEFINED) {
if (strcmp(filename->data, "IPM.Appointment") == 0) {
/* If it's "indicated" twice, we don't want to save 2 calendar entries. */
if (foundCal == 0) {
saveVCalendar (tnef, tmpdir);
}
}
}
if (strcmp(tnef->messageClass, "IPM.Microsoft Mail.Note") == 0) {
if ((saveRTF == 1) && (tnef->subject.size > 0)) {
/* Description */
if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED)))
!= MAPI_UNDEFINED) {
variableLength buf;
if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) {
file = sanitize_filename (tnef->subject.data);
if (!file)
return;
absfilename = g_strconcat (file, ".rtf", NULL);
ifilename = g_build_filename (tmpdir, file, NULL);
g_free (absfilename);
g_free (file);
if ((fptr = fopen(ifilename, "wb"))==NULL) {
printf("ERROR: Error writing file to disk!");
} else {
fwrite (buf.data,
sizeof (BYTE),
buf.size,
fptr);
fclose (fptr);
}
free (buf.data);
}
}
}
}
/* Now process each attachment */
p = tnef->starting_attach.next;
count = 0;
while (p != NULL) {
count++;
/* Make sure it has a size. */
if (p->FileData.size > 0) {
object = 1;
/* See if the contents are stored as "attached data" */
/* Inside the MAPI blocks. */
if ((filedata = MAPIFindProperty (&(p->MAPI),
PROP_TAG (PT_OBJECT, PR_ATTACH_DATA_OBJ)))
== MAPI_UNDEFINED) {
if ((filedata = MAPIFindProperty (&(p->MAPI),
PROP_TAG (PT_BINARY, PR_ATTACH_DATA_OBJ)))
== MAPI_UNDEFINED) {
/* Nope, standard TNEF stuff. */
filedata = &(p->FileData);
object = 0;
}
}
/* See if this is an embedded TNEF stream. */
RealAttachment = 1;
if (object == 1) {
/* This is an "embedded object", so skip the */
/* 16-byte identifier first. */
TNEFStruct emb_tnef;
DWORD signature;
memcpy (&signature, filedata->data + 16, sizeof (DWORD));
if (TNEFCheckForSignature (signature) == 0) {
/* Has a TNEF signature, so process it. */
TNEFInitialize (&emb_tnef);
emb_tnef.Debug = tnef->Debug;
if (TNEFParseMemory ((guchar *) filedata->data + 16,
filedata->size - 16, &emb_tnef) != -1) {
processTnef (&emb_tnef, tmpdir);
RealAttachment = 0;
}
TNEFFree (&emb_tnef);
}
} else {
TNEFStruct emb_tnef;
DWORD signature;
memcpy (&signature, filedata->data, sizeof (DWORD));
if (TNEFCheckForSignature (signature) == 0) {
/* Has a TNEF signature, so process it. */
TNEFInitialize (&emb_tnef);
emb_tnef.Debug = tnef->Debug;
if (TNEFParseMemory ((guchar *) filedata->data,
filedata->size, &emb_tnef) != -1) {
processTnef (&emb_tnef, tmpdir);
RealAttachment = 0;
}
TNEFFree (&emb_tnef);
}
}
if ((RealAttachment == 1) || (saveintermediate == 1)) {
gchar tmpname[20];
/* Ok, it's not an embedded stream, so now we */
/* process it. */
if ((filename = MAPIFindProperty (&(p->MAPI),
PROP_TAG (PT_STRING8, PR_ATTACH_LONG_FILENAME)))
== MAPI_UNDEFINED) {
if ((filename = MAPIFindProperty (&(p->MAPI),
PROP_TAG (PT_STRING8, PR_DISPLAY_NAME)))
== MAPI_UNDEFINED) {
filename = &(p->Title);
}
}
if (filename->size == 1) {
filename->size = 20;
g_sprintf(tmpname, "file_%03i.dat", count);
filename->data = tmpname;
}
absfilename = sanitize_filename (filename->data);
if (!absfilename)
return;
ifilename = g_build_filename (tmpdir, absfilename, NULL);
g_free (absfilename);
if ((fptr = fopen(ifilename, "wb"))==NULL) {
printf("ERROR: Error writing file to disk!");
} else {
if (object == 1) {
fwrite (filedata->data + 16,
sizeof (BYTE),
filedata->size - 16,
fptr);
} else {
fwrite (filedata->data,
sizeof (BYTE),
filedata->size,
fptr);
}
fclose (fptr);
}
}
} /* if size>0 */
p = p->next;
} /* while p!= null */
g_free (ifilename);
}
void
saveVCard (TNEFStruct *tnef,
const gchar *tmpdir)
{
gchar *ifilename;
gchar *absfilename, *file = NULL;
FILE *fptr;
variableLength *vl;
variableLength *pobox, *street, *city, *state, *zip, *country;
dtr thedate;
gint boolean;
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_NAME))) == MAPI_UNDEFINED) {
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) == MAPI_UNDEFINED) {
if (tnef->subject.size > 0) {
file = sanitize_filename (tnef->subject.data);
if (!file)
return;
absfilename = g_strconcat (file, ".vcard", NULL);
} else
absfilename = g_strdup ("unknown.vcard");
} else {
file = sanitize_filename (vl->data);
if (!file)
return;
absfilename = g_strconcat (file, ".vcard", NULL);
}
} else {
file = sanitize_filename (vl->data);
if (!file)
return;
absfilename = g_strconcat (file, ".vcard", NULL);
}
ifilename = g_build_filename (tmpdir, absfilename, NULL);
g_free (file);
g_free (absfilename);
if ((fptr = fopen(ifilename, "wb"))==NULL) {
printf("Error writing file to disk!");
} else {
fprintf(fptr, "BEGIN:VCARD\n");
fprintf(fptr, "VERSION:2.1\n");
if (vl != MAPI_UNDEFINED) {
fprintf(fptr, "FN:%s\n", vl->data);
}
fprintProperty(tnef, fptr, PT_STRING8, PR_NICKNAME, "NICKNAME:%s\n");
fprintUserProp(tnef, fptr, PT_STRING8, 0x8554, "MAILER:Microsoft Outlook %s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_SPOUSE_NAME, "X-EVOLUTION-SPOUSE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_MANAGER_NAME, "X-EVOLUTION-MANAGER:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_ASSISTANT, "X-EVOLUTION-ASSISTANT:%s\n");
/* Organizational */
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) != MAPI_UNDEFINED) {
if (vl->size > 0) {
if ((vl->size == 1) && (vl->data[0] == 0)) {
} else {
fprintf(fptr,"ORG:%s", vl->data);
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DEPARTMENT_NAME))) != MAPI_UNDEFINED) {
fprintf(fptr,";%s", vl->data);
}
fprintf(fptr, "\n");
}
}
}
fprintProperty(tnef, fptr, PT_STRING8, PR_OFFICE_LOCATION, "X-EVOLUTION-OFFICE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_TITLE, "TITLE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_PROFESSION, "ROLE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_BODY, "NOTE:%s\n");
if (tnef->body.size > 0) {
fprintf(fptr, "NOTE;QUOTED-PRINTABLE:");
quotedfprint (fptr, &(tnef->body));
fprintf(fptr,"\n");
}
/* Business Address */
boolean = 0;
if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STREET_ADDRESS))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_LOCALITY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POSTAL_CODE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COUNTRY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if (boolean == 1) {
fprintf(fptr, "ADR;QUOTED-PRINTABLE;WORK:");
if (pobox != MAPI_UNDEFINED) {
quotedfprint (fptr, pobox);
}
fprintf(fptr, ";;");
if (street != MAPI_UNDEFINED) {
quotedfprint (fptr, street);
}
fprintf(fptr, ";");
if (city != MAPI_UNDEFINED) {
quotedfprint (fptr, city);
}
fprintf(fptr, ";");
if (state != MAPI_UNDEFINED) {
quotedfprint (fptr, state);
}
fprintf(fptr, ";");
if (zip != MAPI_UNDEFINED) {
quotedfprint (fptr, zip);
}
fprintf(fptr, ";");
if (country != MAPI_UNDEFINED) {
quotedfprint (fptr, country);
}
fprintf(fptr,"\n");
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801b))) != MAPI_UNDEFINED) {
fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
quotedfprint (fptr, vl);
fprintf(fptr,"\n");
}
}
/* Home Address */
boolean = 0;
if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STREET))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_CITY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if (boolean == 1) {
fprintf(fptr, "ADR;QUOTED-PRINTABLE;HOME:");
if (pobox != MAPI_UNDEFINED) {
quotedfprint (fptr, pobox);
}
fprintf(fptr, ";;");
if (street != MAPI_UNDEFINED) {
quotedfprint (fptr, street);
}
fprintf(fptr, ";");
if (city != MAPI_UNDEFINED) {
quotedfprint (fptr, city);
}
fprintf(fptr, ";");
if (state != MAPI_UNDEFINED) {
quotedfprint (fptr, state);
}
fprintf(fptr, ";");
if (zip != MAPI_UNDEFINED) {
quotedfprint (fptr, zip);
}
fprintf(fptr, ";");
if (country != MAPI_UNDEFINED) {
quotedfprint (fptr, country);
}
fprintf(fptr,"\n");
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801a))) != MAPI_UNDEFINED) {
fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
quotedfprint (fptr, vl);
fprintf(fptr,"\n");
}
}
/* Other Address */
boolean = 0;
if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STREET))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_CITY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
boolean = 1;
}
if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
boolean = 1;
}
if (boolean == 1) {
fprintf(fptr, "ADR;QUOTED-PRINTABLE;OTHER:");
if (pobox != MAPI_UNDEFINED) {
quotedfprint (fptr, pobox);
}
fprintf(fptr, ";;");
if (street != MAPI_UNDEFINED) {
quotedfprint (fptr, street);
}
fprintf(fptr, ";");
if (city != MAPI_UNDEFINED) {
quotedfprint (fptr, city);
}
fprintf(fptr, ";");
if (state != MAPI_UNDEFINED) {
quotedfprint (fptr, state);
}
fprintf(fptr, ";");
if (zip != MAPI_UNDEFINED) {
quotedfprint (fptr, zip);
}
fprintf(fptr, ";");
if (country != MAPI_UNDEFINED) {
quotedfprint (fptr, country);
}
fprintf(fptr,"\n");
}
fprintProperty(tnef, fptr, PT_STRING8, PR_CALLBACK_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-CALLBACK:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_PRIMARY_TELEPHONE_NUMBER, "TEL;PREF:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_MOBILE_TELEPHONE_NUMBER, "TEL;CELL:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_RADIO_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-RADIO:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_CAR_TELEPHONE_NUMBER, "TEL;CAR:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_OTHER_TELEPHONE_NUMBER, "TEL;VOICE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_PAGER_TELEPHONE_NUMBER, "TEL;PAGER:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_TELEX_NUMBER, "TEL;X-EVOLUTION-TELEX:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_ISDN_NUMBER, "TEL;ISDN:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_HOME2_TELEPHONE_NUMBER, "TEL;HOME:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_TTYTDD_PHONE_NUMBER, "TEL;X-EVOLUTION-TTYTDD:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_HOME_TELEPHONE_NUMBER, "TEL;HOME;VOICE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_ASSISTANT_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-ASSISTANT:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_COMPANY_MAIN_PHONE_NUMBER, "TEL;WORK:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_TELEPHONE_NUMBER, "TEL;WORK:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS2_TELEPHONE_NUMBER, "TEL;WORK;VOICE:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_PRIMARY_FAX_NUMBER, "TEL;PREF;FAX:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_FAX_NUMBER, "TEL;WORK;FAX:%s\n");
fprintProperty(tnef, fptr, PT_STRING8, PR_HOME_FAX_NUMBER, "TEL;HOME;FAX:%s\n");
/* Email addresses */
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8083))) == MAPI_UNDEFINED) {
vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8084));
}
if (vl != MAPI_UNDEFINED) {
if (vl->size > 0)
fprintf(fptr, "EMAIL:%s\n", vl->data);
}
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8093))) == MAPI_UNDEFINED) {
vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8094));
}
if (vl != MAPI_UNDEFINED) {
if (vl->size > 0)
fprintf(fptr, "EMAIL:%s\n", vl->data);
}
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a3))) == MAPI_UNDEFINED) {
vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a4));
}
if (vl != MAPI_UNDEFINED) {
if (vl->size > 0)
fprintf(fptr, "EMAIL:%s\n", vl->data);
}
fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_HOME_PAGE, "URL:%s\n");
fprintUserProp(tnef, fptr, PT_STRING8, 0x80d8, "FBURL:%s\n");
/* Birthday */
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_BIRTHDAY))) != MAPI_UNDEFINED) {
fprintf(fptr, "BDAY:");
MAPISysTimetoDTR ((guchar *) vl->data, &thedate);
fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
}
/* Anniversary */
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_WEDDING_ANNIVERSARY))) != MAPI_UNDEFINED) {
fprintf(fptr, "X-EVOLUTION-ANNIVERSARY:");
MAPISysTimetoDTR ((guchar *) vl->data, &thedate);
fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
}
fprintf(fptr, "END:VCARD\n");
fclose (fptr);
}
g_free (ifilename);
}
guchar getRruleCount (guchar a, guchar b) {
return ((a << 8) | b);
}
guchar getRruleMonthNum (guchar a, guchar b) {
switch (a) {
case 0x00:
switch (b) {
case 0x00:
/* Jan */
return (1);
case 0xA3:
/* May */
return (5);
case 0xAE:
/* Nov */
return (11);
}
break;
case 0x60:
switch (b) {
case 0xAE:
/* Feb */
return (2);
case 0x51:
/* Jun */
return (6);
}
break;
case 0xE0:
switch (b) {
case 0x4B:
/* Mar */
return (3);
case 0x56:
/* Sep */
return (9);
}
break;
case 0x40:
switch (b) {
case 0xFA:
/* Apr */
return (4);
}
break;
case 0x20:
if (b == 0xFA) {
/* Jul */
return (7);
}
break;
case 0x80:
if (b == 0xA8) {
/* Aug */
return (8);
}
break;
case 0xA0:
if (b == 0xFF) {
/* Oct */
return (10);
}
break;
case 0xC0:
if (b == 0x56) {
return (12);
}
}
/* Error */
return (0);
}
gchar * getRruleDayname (guchar a) {
static gchar daystring[25];
*daystring = 0;
if (a & 0x01) {
strcat(daystring, "SU,");
}
if (a & 0x02) {
strcat(daystring, "MO,");
}
if (a & 0x04) {
strcat(daystring, "TU,");
}
if (a & 0x08) {
strcat(daystring, "WE,");
}
if (a & 0x10) {
strcat(daystring, "TH,");
}
if (a & 0x20) {
strcat(daystring, "FR,");
}
if (a & 0x40) {
strcat(daystring, "SA,");
}
if (strlen (daystring)) {
daystring[strlen (daystring) - 1] = 0;
}
return (daystring);
}
void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef)
{
variableLength *filename;
if (size < 0x1F) {
return;
}
fprintf(fptr, "RRULE:FREQ=");
if (recur_data[0x04] == 0x0A) {
fprintf(fptr, "DAILY");
if (recur_data[0x16] == 0x23 || recur_data[0x16] == 0x22 ||
recur_data[0x16] == 0x21) {
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_I2, 0x0011))) != MAPI_UNDEFINED) {
fprintf(fptr, ";INTERVAL=%d", *(filename->data));
}
if (recur_data[0x16] == 0x22 || recur_data[0x16] == 0x21) {
fprintf(fptr, ";COUNT=%d",
getRruleCount (recur_data[0x1B], recur_data[0x1A]));
}
} else if (recur_data[0x16] == 0x3E) {
fprintf(fptr, ";BYDAY=MO,TU,WE,TH,FR");
if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
fprintf(fptr, ";COUNT=%d",
getRruleCount (recur_data[0x1F], recur_data[0x1E]));
}
}
} else if (recur_data[0x04] == 0x0B) {
fprintf(fptr, "WEEKLY;INTERVAL=%d;BYDAY=%s",
recur_data[0x0E], getRruleDayname (recur_data[0x16]));
if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
fprintf(fptr, ";COUNT=%d",
getRruleCount (recur_data[0x1F], recur_data[0x1E]));
}
} else if (recur_data[0x04] == 0x0C) {
fprintf(fptr, "MONTHLY");
if (recur_data[0x06] == 0x02) {
fprintf(fptr, ";INTERVAL=%d;BYMONTHDAY=%d", recur_data[0x0E],
recur_data[0x16]);
if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x1F],
recur_data[0x1E]));
}
} else if (recur_data[0x06] == 0x03) {
fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d;INTERVAL=%d",
getRruleDayname (recur_data[0x16]),
recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A],
recur_data[0x0E]);
if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x23],
recur_data[0x22]));
}
}
} else if (recur_data[0x04] == 0x0D) {
fprintf(fptr, "YEARLY;BYMONTH=%d",
getRruleMonthNum (recur_data[0x0A], recur_data[0x0B]));
if (recur_data[0x06] == 0x02) {
fprintf(fptr, ";BYMONTHDAY=%d", recur_data[0x16]);
} else if (recur_data[0x06] == 0x03) {
fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d",
getRruleDayname (recur_data[0x16]),
recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A]);
}
if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x23],
recur_data[0x22]));
}
}
fprintf(fptr, "\n");
}
void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir) {
gchar *ifilename;
variableLength *filename;
gchar *charptr, *charptr2;
FILE *fptr;
gint index;
DWORD *dword_ptr;
dtr thedate;
ifilename = g_build_filename (tmpdir, "calendar.vcf", NULL);
printf("%s\n", ifilename);
if ((fptr = fopen(ifilename, "wb"))==NULL) {
printf("Error writing file to disk!");
} else {
fprintf(fptr, "BEGIN:VCALENDAR\n");
if (tnef->messageClass[0] != 0) {
charptr2 = tnef->messageClass;
charptr = charptr2;
while (*charptr != 0) {
if (*charptr == '.') {
charptr2 = charptr;
}
charptr++;
}
if (strcmp(charptr2, ".MtgCncl") == 0) {
fprintf(fptr, "METHOD:CANCEL\n");
} else {
fprintf(fptr, "METHOD:REQUEST\n");
}
} else {
fprintf(fptr, "METHOD:REQUEST\n");
}
fprintf(fptr, "VERSION:2.0\n");
fprintf(fptr, "BEGIN:VEVENT\n");
/* UID
* After alot of comparisons, I'm reasonably sure this is totally
* wrong. But it's not really necessary. */
/* I think it only exists to connect future modification entries to
* this entry. so as long as it's incorrectly interpreted the same way
* every time, it should be ok :) */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, 0x3))) == MAPI_UNDEFINED) {
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, 0x23))) == MAPI_UNDEFINED) {
filename = NULL;
}
}
if (filename != NULL) {
fprintf(fptr, "UID:");
for (index = 0; index < filename->size; index++) {
fprintf(fptr,"%02X", (guchar)filename->data[index]);
}
fprintf(fptr,"\n");
}
/* Sequence */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_LONG, 0x8201))) != MAPI_UNDEFINED) {
dword_ptr = (DWORD *) filename->data;
fprintf(fptr, "SEQUENCE:%i\n", (gint) *dword_ptr);
}
if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, PR_SENDER_SEARCH_KEY)))
!= MAPI_UNDEFINED) {
charptr = filename->data;
charptr2 = strstr(charptr, ":");
if (charptr2 == NULL)
charptr2 = charptr;
else
charptr2++;
fprintf(fptr, "ORGANIZER;CN=\"%s\":MAILTO:%s\n",
charptr2, charptr2);
}
/* Required Attendees */
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, 0x823b))) != MAPI_UNDEFINED) {
/* We have a list of required participants, so
write them out. */
if (filename->size > 1) {
charptr = filename->data - 1;
while (charptr != NULL) {
charptr++;
charptr2 = strstr(charptr, ";");
if (charptr2 != NULL) {
*charptr2 = 0;
}
while (*charptr == ' ')
charptr++;
fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
charptr, charptr);
charptr = charptr2;
}
}
/* Optional attendees */
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, 0x823c))) != MAPI_UNDEFINED) {
/* The list of optional participants */
if (filename->size > 1) {
charptr = filename->data - 1;
while (charptr != NULL) {
charptr++;
charptr2 = strstr(charptr, ";");
if (charptr2 != NULL) {
*charptr2 = 0;
}
while (*charptr == ' ')
charptr++;
fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
fprintf(fptr, "ROLE=OPT-PARTICIPANT;RSVP=TRUE;");
fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
charptr, charptr);
charptr = charptr2;
}
}
}
} else if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, 0x8238))) != MAPI_UNDEFINED) {
if (filename->size > 1) {
charptr = filename->data - 1;
while (charptr != NULL) {
charptr++;
charptr2 = strstr(charptr, ";");
if (charptr2 != NULL) {
*charptr2 = 0;
}
while (*charptr == ' ')
charptr++;
fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
charptr, charptr);
charptr = charptr2;
}
}
}
/* Summary */
filename = NULL;
if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC)))
!= MAPI_UNDEFINED) {
fprintf(fptr, "SUMMARY:");
cstylefprint (fptr, filename);
fprintf(fptr, "\n");
}
/* Description */
if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED)))
!= MAPI_UNDEFINED) {
variableLength buf;
if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) {
fprintf(fptr, "DESCRIPTION:");
printRtf (fptr, &buf);
free (buf.data);
}
}
/* Location */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, 0x0002))) == MAPI_UNDEFINED) {
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_STRING8, 0x8208))) == MAPI_UNDEFINED) {
filename = NULL;
}
}
if (filename != NULL) {
fprintf(fptr,"LOCATION: %s\n", filename->data);
}
/* Date Start */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_SYSTIME, 0x820d))) == MAPI_UNDEFINED) {
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_SYSTIME, 0x8516))) == MAPI_UNDEFINED) {
filename = NULL;
}
}
if (filename != NULL) {
fprintf(fptr, "DTSTART:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
/* Date End */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_SYSTIME, 0x820e))) == MAPI_UNDEFINED) {
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_SYSTIME, 0x8517))) == MAPI_UNDEFINED) {
filename = NULL;
}
}
if (filename != NULL) {
fprintf(fptr, "DTEND:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
/* Date Stamp */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_SYSTIME, 0x8202))) != MAPI_UNDEFINED) {
fprintf(fptr, "CREATED:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
/* Class */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_BOOLEAN, 0x8506))) != MAPI_UNDEFINED) {
dword_ptr = (DWORD *) filename->data;
fprintf(fptr, "CLASS:" );
if (*dword_ptr == 1) {
fprintf(fptr,"PRIVATE\n");
} else {
fprintf(fptr,"PUBLIC\n");
}
}
/* Recurrence */
filename = NULL;
if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
PROP_TAG (PT_BINARY, 0x8216))) != MAPI_UNDEFINED) {
printRrule (fptr, filename->data, filename->size, tnef);
}
/* Wrap it up */
fprintf(fptr, "END:VEVENT\n");
fprintf(fptr, "END:VCALENDAR\n");
fclose (fptr);
}
g_free (ifilename);
}
void saveVTask (TNEFStruct *tnef, const gchar *tmpdir) {
variableLength *vl;
variableLength *filename;
gint index;
gchar *ifilename;
gchar *absfilename, *file;
gchar *charptr, *charptr2;
dtr thedate;
FILE *fptr;
DWORD *dword_ptr;
vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC));
if (vl == MAPI_UNDEFINED) {
return;
}
index = strlen (vl->data);
while (vl->data[index] == ' ')
vl->data[index--] = 0;
file = sanitize_filename (vl->data);
if (!file)
return;
absfilename = g_strconcat (file, ".vcf", NULL);
ifilename = g_build_filename (tmpdir, absfilename, NULL);
g_free (file);
g_free (absfilename);
printf("%s\n", ifilename);
if ((fptr = fopen(ifilename, "wb"))==NULL) {
printf("Error writing file to disk!");
} else {
fprintf(fptr, "BEGIN:VCALENDAR\n");
fprintf(fptr, "VERSION:2.0\n");
fprintf(fptr, "METHOD:PUBLISH\n");
filename = NULL;
fprintf(fptr, "BEGIN:VTODO\n");
if (tnef->messageID[0] != 0) {
fprintf(fptr,"UID:%s\n", tnef->messageID);
}
filename = MAPIFindUserProp (&(tnef->MapiProperties), \
PROP_TAG (PT_STRING8, 0x8122));
if (filename != MAPI_UNDEFINED) {
fprintf(fptr, "ORGANIZER:%s\n", filename->data);
}
if ((filename = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_TO))) != MAPI_UNDEFINED) {
filename = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x811f));
}
if ((filename != MAPI_UNDEFINED) && (filename->size > 1)) {
charptr = filename->data - 1;
while (charptr != NULL) {
charptr++;
charptr2 = strstr(charptr, ";");
if (charptr2 != NULL) {
*charptr2 = 0;
}
while (*charptr == ' ')
charptr++;
fprintf(fptr, "ATTENDEE;CN=%s;ROLE=REQ-PARTICIPANT:%s\n", charptr, charptr);
charptr = charptr2;
}
}
if (tnef->subject.size > 0) {
fprintf(fptr,"SUMMARY:");
cstylefprint (fptr,&(tnef->subject));
fprintf(fptr,"\n");
}
if (tnef->body.size > 0) {
fprintf(fptr,"DESCRIPTION:");
cstylefprint (fptr,&(tnef->body));
fprintf(fptr,"\n");
}
filename = MAPIFindProperty (&(tnef->MapiProperties), \
PROP_TAG (PT_SYSTIME, PR_CREATION_TIME));
if (filename != MAPI_UNDEFINED) {
fprintf(fptr, "DTSTAMP:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
filename = MAPIFindUserProp (&(tnef->MapiProperties), \
PROP_TAG (PT_SYSTIME, 0x8517));
if (filename != MAPI_UNDEFINED) {
fprintf(fptr, "DUE:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
filename = MAPIFindProperty (&(tnef->MapiProperties), \
PROP_TAG (PT_SYSTIME, PR_LAST_MODIFICATION_TIME));
if (filename != MAPI_UNDEFINED) {
fprintf(fptr, "LAST-MODIFIED:");
MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
thedate.wYear, thedate.wMonth, thedate.wDay,
thedate.wHour, thedate.wMinute, thedate.wSecond);
}
/* Class */
filename = MAPIFindUserProp (&(tnef->MapiProperties), \
PROP_TAG (PT_BOOLEAN, 0x8506));
if (filename != MAPI_UNDEFINED) {
dword_ptr = (DWORD *) filename->data;
fprintf(fptr, "CLASS:" );
if (*dword_ptr == 1) {
fprintf(fptr,"PRIVATE\n");
} else {
fprintf(fptr,"PUBLIC\n");
}
}
fprintf(fptr, "END:VTODO\n");
fprintf(fptr, "END:VCALENDAR\n");
fclose (fptr);
}
g_free (ifilename);
}
void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) {
variableLength *vl;
if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) {
if (vl->size > 0) {
if ((vl->size == 1) && (vl->data[0] == 0)) {
} else {
fprintf (fptr, text, vl->data);
}
}
}
}
void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) {
variableLength *vl;
if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) {
if (vl->size > 0) {
if ((vl->size == 1) && (vl->data[0] == 0)) {
} else {
fprintf (fptr, text, vl->data);
}
}
}
}
void quotedfprint (FILE *fptr, variableLength *vl) {
gint index;
for (index = 0; index < vl->size - 1; index++) {
if (vl->data[index] == '\n') {
fprintf(fptr, "=0A");
} else if (vl->data[index] == '\r') {
} else {
fprintf(fptr, "%c", vl->data[index]);
}
}
}
void cstylefprint (FILE *fptr, variableLength *vl) {
gint index;
for (index = 0; index < vl->size - 1; index++) {
if (vl->data[index] == '\n') {
fprintf(fptr, "\\n");
} else if (vl->data[index] == '\r') {
/* Print nothing. */
} else if (vl->data[index] == ';') {
fprintf(fptr, "\\;");
} else if (vl->data[index] == ',') {
fprintf(fptr, "\\,");
} else if (vl->data[index] == '\\') {
fprintf(fptr, "\\");
} else {
fprintf(fptr, "%c", vl->data[index]);
}
}
}
void printRtf (FILE *fptr, variableLength *vl) {
gint index;
gchar *byte;
gint brace_ct;
gint key;
key = 0;
brace_ct = 0;
for (index = 0, byte = vl->data; index < vl->size; index++, byte++) {
if (*byte == '}') {
brace_ct--;
key = 0;
continue;
}
if (*byte == '{') {
brace_ct++;
continue;
}
if (*byte == '\\') {
key = 1;
}
if (isspace (*byte)) {
key = 0;
}
if ((brace_ct == 1) && (key == 0)) {
if (*byte == '\n') {
fprintf(fptr, "\\n");
} else if (*byte == '\r') {
/* Print nothing. */
} else if (*byte == ';') {
fprintf(fptr, "\\;");
} else if (*byte == ',') {
fprintf(fptr, "\\,");
} else if (*byte == '\\') {
fprintf(fptr, "\\");
} else {
fprintf(fptr, "%c", *byte);
}
}
}
fprintf(fptr, "\n");
}