diff --git a/include/file.h b/include/file.h index 9a57f3e..36e0e1e 100644 --- a/include/file.h +++ b/include/file.h @@ -18,6 +18,14 @@ #ifndef FILE_H #define FILE_H +#include "mail.h" + +#include + char* generate_safe_dirname(); +int base64_decode_file(const char* directory, const struct email_t* mail); + +bool file_exists(const char* filename); + #endif /* FILE_H */ diff --git a/src/attach.c b/src/attach.c index 014808c..d012136 100644 --- a/src/attach.c +++ b/src/attach.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Generates an email struct from the given eml text. If the content is * multipart, it will be slit up into several email_ts. This expansion is done @@ -284,7 +285,7 @@ char* attach_files(char* message, size_t len){ } /* Now we can start the real work! */ - const char* storage_dir = generate_safe_dirname(); + char* storage_dir = generate_safe_dirname(); if(storage_dir == NULL){ fprintf(stderr,"Failed to get mail storage directory!\n"); goto finish; @@ -293,11 +294,17 @@ char* attach_files(char* message, size_t len){ printf("Storing mail messages into directory [%s]\n", storage_dir); } + if(mkdir(storage_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0){ + perror("Failed to create storage directory!"); + goto finish; + + } if(replace_base64_files(email, storage_dir) < 0){ fprintf(stderr, "Failed to store base64 messages!\n"); goto finish; } + free(storage_dir); /* Announce our presence via header */ if(append_header(email,"X-Mailattached", instance_id) < 0){ @@ -329,7 +336,16 @@ int replace_base64_files(struct email_t* mail, const char* dirname){ return 0; } - + if(!mail->base64_encoded){ + return 0; + } + + if(base64_decode_file(dirname, mail) < 0){ + fprintf(stderr, "Failed to decode base64 file\n!"); + return -1; + } + /* Replace the mail message with some html text TODO */ return 0; } + diff --git a/src/file.c b/src/file.c index fcd3f34..f07b82d 100644 --- a/src/file.c +++ b/src/file.c @@ -17,6 +17,7 @@ #include "file.h" #include "config.h" +#include "base64.h" #include #include @@ -78,3 +79,82 @@ char* generate_safe_dirname(){ return dir_id; } +int base64_decode_file(const char* directory, const struct email_t* mail){ + + if(!mail->base64_encoded){ + return -1; + } + + if(directory == NULL || mail == NULL || mail->file_info.name == NULL){ + + /* I don't know how I should call that file! */ + return 0; + } + size_t dec_len = 0; + unsigned char* decoded = base64_decode( + ((unsigned char*)mail->message+mail->body_offset), + (mail->message_length-mail->body_offset), + &dec_len); + + if(decoded == NULL){ + fprintf(stderr, "Failed to decode base64 message\n"); + return -1; + } + + + size_t fn_len = strlen(mail->file_info.name) + strlen(directory) + 1; + + char* filename = malloc(fn_len); + if(filename == NULL){ + free(decoded); + return -1; + } + + memset(filename, 0, fn_len); + strcat(filename, directory); + strcat(filename, mail->file_info.name); + + bool exists = false; + for(size_t i = 0; i < 10; i++){ + exists = file_exists(filename); + if(exists){ + free(filename); + fn_len = strlen(mail->file_info.name) + + strlen(directory) + 20; + filename = malloc(fn_len); + snprintf(filename, fn_len, "%s%i-%s",directory, + rand(), mail->file_info.name); + } + } + if(exists){ + /* What?*/ + free(filename); + free(decoded); + return -1; + } + + FILE* outfile = fopen(filename, "w+"); + if(outfile == NULL){ + perror("Failed to open base64 out file"); + free(filename); + free(decoded); + return -1; + } + + fwrite(decoded, dec_len, 1, outfile); + fclose(outfile); + free(filename); + free(decoded); + return 0; + +} + +bool file_exists(const char* filename){ + struct stat buffer; + int exist = stat(filename,&buffer); + if(exist >= 0){ + return true; + } else{ + return false; + } +}