Skip to content

Instantly share code, notes, and snippets.

@ohwgiles
Last active May 26, 2018 07:13
Show Gist options
  • Save ohwgiles/be14e9e9d010d4435a93389e618e2ee9 to your computer and use it in GitHub Desktop.
Save ohwgiles/be14e9e9d010d4435a93389e618e2ee9 to your computer and use it in GitHub Desktop.
Extract TNEF to GMimeParts
#include <stddef.h>
#include <stdio.h>
#include <ytnef.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <gmime/gmime.h>
GSList* attachments_from_tnef_buffer(char* buffer, int size)
{
GSList* res = NULL;
TNEFStruct tn = {0};
if(TNEFParseMemory(buffer, size, &tn) != 0)
return res;
for(Attachment* p = tn.starting_attach.next; p; p = p->next) {
variableLength* filename;
if((filename = MAPIFindProperty(&(p->MAPI), PROP_TAG(PT_STRING8, PR_ATTACH_LONG_FILENAME))) == MAPI_UNDEFINED)
filename = &(p->Title);
GMimeStream* stream = g_mime_stream_mem_new_with_buffer(p->FileData.data, p->FileData.size);
GMimeDataWrapper* data = g_mime_data_wrapper_new_with_stream(stream, GMIME_CONTENT_ENCODING_BINARY);
GMimePart* part = g_mime_part_new();
g_mime_part_set_content(part, data);
g_mime_part_set_filename(part, filename->data);
g_object_unref(data);
g_object_unref(stream);
res = g_slist_append(res, part);
}
TNEFFree(&tn);
return res;
}
int main(int argc, char** argv)
{
g_mime_init();
struct stat sb;
int fd = open(argv[1], O_RDONLY);
if(fd == -1)
return perror("open"), -1;
if(fstat(fd, &sb) == -1)
return perror("fstat"), -1;
char* buf = (char*) mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if(buf == NULL)
return perror("mmap"), -1;
GSList* attachments = attachments_from_tnef_buffer(buf, sb.st_size);
munmap(buf, sb.st_size);
close(fd);
for(GSList* a = attachments; a; a = a->next)
printf("found %s\n", g_mime_part_get_filename(GMIME_PART(a->data)));
g_slist_free_full(attachments, g_object_unref);
g_mime_shutdown();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment