static gboolean tnef_parse (MimeParser *parser, MimeInfo *mimeinfo) { TNEFStruct *tnef; MimeInfo *sub_info = NULL; variableLength *tmp_var; Attachment *att; int parse_result = 0; gboolean cal_done = FALSE; if (!procmime_decode_content(mimeinfo)) { debug_print("error decoding\n"); return FALSE; } debug_print("Tnef parser parsing part (%d).\n", mimeinfo->length); if (mimeinfo->content == MIMECONTENT_FILE) debug_print("content: %s\n", mimeinfo->data.filename); else debug_print("contents in memory (len %zd)\n", strlen(mimeinfo->data.mem)); tnef = g_new0(TNEFStruct, 1); TNEFInitialize(tnef); tnef->Debug = debug_get_mode(); if (mimeinfo->content == MIMECONTENT_MEM) parse_result = TNEFParseMemory(mimeinfo->data.mem, mimeinfo->length, tnef); else parse_result = TNEFParseFile(mimeinfo->data.filename, tnef); mimeinfo->type = MIMETYPE_MULTIPART; mimeinfo->subtype = g_strdup("mixed"); g_hash_table_insert(mimeinfo->typeparameters, g_strdup("description"), g_strdup("Parsed from MS-TNEF")); if (parse_result != 0) { g_warning("Failed to parse TNEF data."); TNEFFree(tnef); return FALSE; } sub_info = NULL; if (tnef->messageClass[0] != '\0') { if (strcmp(tnef->messageClass, "IPM.Contact") == 0) sub_info = tnef_parse_vcard(tnef); else if (strcmp(tnef->messageClass, "IPM.Task") == 0) sub_info = tnef_parse_vtask(tnef); else if (strcmp(tnef->messageClass, "IPM.Appointment") == 0) { sub_info = tnef_parse_vcal(tnef); cal_done = TRUE; } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; if (tnef->MapiProperties.count > 0) { tmp_var = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG(PT_BINARY,PR_RTF_COMPRESSED)); if (tmp_var != MAPI_UNDEFINED) { sub_info = tnef_parse_rtf(tnef, tmp_var); } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; tmp_var = MAPIFindUserProp(&(tnef->MapiProperties), PROP_TAG(PT_STRING8,0x24)); if (tmp_var != MAPI_UNDEFINED) { if (!cal_done && strcmp(tmp_var->data, "IPM.Appointment") == 0) { sub_info = tnef_parse_vcal(tnef); } } if (sub_info) g_node_append(mimeinfo->node, sub_info->node); sub_info = NULL; att = tnef->starting_attach.next; while (att) { gchar *filename = NULL; gboolean is_object = TRUE; DWORD signature; tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(30,0x3707)); if (tmp_var == MAPI_UNDEFINED) tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(30,0x3001)); if (tmp_var == MAPI_UNDEFINED) tmp_var = &(att->Title); if (tmp_var->data) filename = g_strdup(tmp_var->data); tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(PT_OBJECT, PR_ATTACH_DATA_OBJ)); if (tmp_var == MAPI_UNDEFINED) tmp_var = MAPIFindProperty(&(att->MAPI), PROP_TAG(PT_BINARY, PR_ATTACH_DATA_OBJ)); if (tmp_var == MAPI_UNDEFINED) { tmp_var = &(att->FileData); is_object = FALSE; } sub_info = tnef_dump_file(filename, tmp_var->data + (is_object ? 16:0), tmp_var->size - (is_object ? 16:0)); if (sub_info) g_node_append(mimeinfo->node, sub_info->node); memcpy(&signature, tmp_var->data+(is_object ? 16:0), sizeof(DWORD)); if (TNEFCheckForSignature(signature) == 0) { debug_print("that's TNEF stuff, process it\n"); tnef_parse(parser, sub_info); } sub_info = NULL; att = att->next; g_free(filename); } TNEFFree(tnef); return TRUE; }
void processTnef(TNEFStruct *tnef) { variableLength *filename; variableLength *filedata; Attachment *p; int RealAttachment; int object; char * ifilename; int i, count; int foundCal=0; FILE *fptr; ifilename = (char *) g_malloc(sizeof(char) * 256); /* 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); } if (strcmp(tnef->messageClass, "IPM.Task") == 0) { saveVTask(tnef); } if (strcmp(tnef->messageClass, "IPM.Appointment") == 0) { saveVCalendar(tnef); 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); } } } 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; buf = (variableLength *)g_malloc (sizeof(variableLength)); buf->data=""; buf->size=0; if ((buf->data = DecompressRTF(filename, &(buf->size))) != NULL) { if (filepath == NULL) { sprintf(ifilename, "%s.rtf", tnef->subject.data); } else { sprintf(ifilename, "%s/%s.rtf", filepath, tnef->subject.data); } for(i=0; i<strlen(ifilename); i++) if (ifilename[i] == ' ') ifilename[i] = '_'; 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); buf->data=""; buf->size=0; } } } } /* 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; emb_tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct)); 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(filedata->data+16, filedata->size-16, emb_tnef) != -1) { processTnef(emb_tnef); RealAttachment = 0; } TNEFFree(emb_tnef); } } else { TNEFStruct *emb_tnef; emb_tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct)); 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(filedata->data, filedata->size, emb_tnef) != -1) { processTnef(emb_tnef); RealAttachment = 0; } TNEFFree(emb_tnef); } } if ((RealAttachment == 1) || (saveintermediate == 1)) { /* Ok, it's not an embedded stream, so now we */ /* process it. */ if ((filename = MAPIFindProperty(&(p->MAPI), PROP_TAG(30,0x3707))) == MAPI_UNDEFINED) { if ((filename = MAPIFindProperty(&(p->MAPI), PROP_TAG(30,0x3001))) == MAPI_UNDEFINED) { filename = &(p->Title); } } if (filename->size == 1) { filename = (variableLength*)malloc(sizeof(variableLength)); filename->size = 20; filename->data = (char*)malloc(20); sprintf(filename->data, "file_%03i.dat", count); } if (filepath == NULL) { sprintf(ifilename, "%s", filename->data); } else { sprintf(ifilename, "%s/%s", filepath, filename->data); } for(i=0; i<strlen(ifilename); i++) if (ifilename[i] == ' ') ifilename[i] = '_'; 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); }