Example #1
0
File: main.c Project: georox/ytnef
int main(int argc, char ** argv) {
    int index,i;

//    printf("Size of WORD is %i\n", sizeof(WORD));
//    printf("Size of DWORD is %i\n", sizeof(DWORD));
//    printf("Size of DDWORD is %i\n", sizeof(DDWORD));

    if (argc == 1) {
        printf("You must specify files to parse\n");
        PrintHelp();
        return -1;
    }
    
    for(i=1; i<argc; i++) {
        if (argv[i][0] == '-') {
            switch (argv[i][1]) {
                case 'v': verbose++;
                          break;
            }
            continue;
        }
        TNEFInitialize(&TNEF);
        TNEF.Debug = verbose;
        if (TNEFParseFile(argv[i], &TNEF) == -1) {
            printf("ERROR processing file\n");
            continue;
        }
        PrintTNEF(TNEF);
        TNEFFree(&TNEF);
    }
}
Example #2
0
void
org_gnome_format_tnef(void *ep, EMFormatHookTarget *t)
{
	char *tmpdir = NULL, *name = NULL;
	CamelStream *out;
	struct dirent *d;
	DIR *dir;
	CamelMultipart *mp;
	CamelMimePart *mainpart;
	CamelDataWrapper *content;
	int len;
	TNEFStruct *tnef;
	tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct));

	tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
	if (tmpdir == NULL)
		return;

	filepath = tmpdir;

	name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL);

	out = camel_stream_fs_new_with_name(name, O_RDWR|O_CREAT, 0666);
	if (out == NULL)
	    goto fail;
	content = camel_medium_get_content_object((CamelMedium *)t->part);
	if (content == NULL)
		goto fail;
	if (camel_data_wrapper_decode_to_stream(content, out) == -1
	    || camel_stream_close(out) == -1) {
		camel_object_unref(out);
 		goto fail;
	}
	camel_object_unref(out);

	/* Extracting the winmail.dat */
        TNEFInitialize(tnef);
	tnef->Debug = verbose;
        if (TNEFParseFile(name, tnef) == -1) {
            printf("ERROR processing file\n");
        }
	processTnef(tnef);

        TNEFFree(tnef);
	/* Extraction done */

	dir = opendir(tmpdir);
	if (dir == NULL)
	    goto fail;

	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_object((CamelMedium *)mainpart, (CamelDataWrapper *)mp);

	while ((d = readdir(dir))) {
		CamelMimePart *part;
		CamelDataWrapper *content;
		CamelStream *stream;
		char *path;
		const char *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);
		content = camel_data_wrapper_new();
		camel_data_wrapper_construct_from_stream(content, stream);
		camel_object_unref(stream);

		part = camel_mime_part_new();
		camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_BINARY);

		camel_medium_set_content_object((CamelMedium *)part, content);
		camel_object_unref(content);

		type = em_utils_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);
	}

	closedir(dir);

	len = t->format->part_id->len;
	g_string_append_printf(t->format->part_id, ".tnef");

	if (camel_multipart_get_number(mp) > 0)
		em_format_part_as(t->format, t->stream, mainpart, "multipart/mixed");
	else if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);

	g_string_truncate(t->format->part_id, len);

	camel_object_unref(mainpart);

	goto ok;
 fail:
	if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);
 ok:
	g_free(name);
	g_free(tmpdir);
}
Example #3
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 #4
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);
}