Example #1
0
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;
}
Example #2
0
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);
}