diff --git a/include/attach.h b/include/attach.h index 78bdcf2..e127ae4 100644 --- a/include/attach.h +++ b/include/attach.h @@ -19,8 +19,22 @@ #define ATTACH_H #include -#include +#include -char* attach_files(FILE* buffer); +struct email_t{ + char* message; + /* From the below values you can say pretty much anything about the + * message. The line delimiting body and header is left out. The header + * len includes the last \r\n of the header. If header len is zero, + * there was no clear distinction between header and body... + */ + size_t header_len, body_offset, message_length; +}; + +struct email_t mail_from_text(char* message, size_t length); +void redetect_body_head(struct email_t* mail); + + +char* attach_files(char* message, size_t len); #endif /* ATTACH_H */ diff --git a/include/tools.h b/include/tools.h new file mode 100644 index 0000000..3483fe9 --- /dev/null +++ b/include/tools.h @@ -0,0 +1,26 @@ +/* + * tools.h - Utility functions + * The author licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef TOOLS_H +#define TOOLS_H + +#include + +const char* insert_string(char * destination, const char* source, + size_t dest_orig_len, size_t offset); + +#endif /* TOOLS_H */ diff --git a/src/attach.c b/src/attach.c index e014650..ca9b9ca 100644 --- a/src/attach.c +++ b/src/attach.c @@ -18,23 +18,71 @@ #include "attach.h" #include +#include +#include +#include #include -char* attach_files(FILE* buffer){ - fseek(buffer, 0, SEEK_END); - size_t len = ftell(buffer); +struct email_t mail_from_text(char* message, size_t length){ + + struct email_t mail; + memset(&mail, 0, sizeof(mail)); + mail.message = message; + mail.message_length = length; + + redetect_body_head(&mail); - char* new_body = malloc(len + 1); - if(new_body == NULL){ - return NULL; - } - memset(new_body,0, len + 1); - fseek(buffer, 0, SEEK_SET); - if(fread(new_body, 1, len, buffer) <= 0){ - perror("Failed to read file buffer"); - free(new_body); - } - - return new_body; + return mail; +} + +void redetect_body_head(struct email_t* mail){ + + char* last_lf = NULL; + char* body_start = NULL; + bool found_alnum = false; + for(size_t i = 0; i < mail->message_length; i++){ + if(mail->message[i] == '\n' && !found_alnum){ + body_start = &(mail->message[i+1]); + break; + + }else if(mail->message[i] == '\n'){ + last_lf = &(mail->message[i]); + found_alnum = false; + }else if(isalnum(mail->message[i])){ + found_alnum = true; + } + } + + /* In that case we only have a body and no header, or something along + * those lines... In any case, if postfix delivers that to us, something + * is probably wrong! + */ + + if(body_start == NULL) { + fprintf(stderr, "Received message without header!"); + mail->header_len = 0; + mail->body_offset = 0; + return; + } + + mail->body_offset = body_start - mail->message; + mail->header_len = last_lf - mail->message; + return; + + +} + +char* attach_files(char* message, size_t len){ + + struct email_t email = mail_from_text(message,len); + + printf("Received message header: [%.*s]\n", email.header_len, + email.message); + printf("Received message body: [%s]\n", + email.message + email.body_offset); + + /* Now we have a null terminated body which we can edit! */ + + return email.message; } diff --git a/src/main.c b/src/main.c index 712e51b..800f7ab 100644 --- a/src/main.c +++ b/src/main.c @@ -65,7 +65,7 @@ void* client_handle_async(void* params){ } int n; /* message byte size */ - char buf[10]; + char buf[1000]; struct pollfd fds[2]; memset(fds, 0 , sizeof(fds)); fds[0].fd = cli->fd; @@ -84,17 +84,17 @@ void* client_handle_async(void* params){ while(poll(fds, 2, timeout) > 0){ for(size_t i = 0; i < 2; i++){ + if(!(fds[i].revents & POLLIN)){ continue; } + bzero(buf, sizeof(buf)); n = read(fds[i].fd, buf, sizeof(buf)-1); if (n <= 0) { goto closeup; } - printf("%lu:[%s]", i, buf); - if(i==0 && !in_body){ /* As long as we are outside the real mail body @@ -112,7 +112,7 @@ void* client_handle_async(void* params){ write((fds[!i].fd), input_buffer+(in_len-n), body_offs-(in_len-n)); - printf("Beginning of body found! " + printf("Beginning of message found! " "Awaiting end...\n"); }else{ @@ -124,22 +124,35 @@ void* client_handle_async(void* params){ */ in_len += n; input_buffer = realloc(input_buffer, in_len); - strncat(input_buffer,buf, n); + strncat(input_buffer, buf, n); body_p = detect_end_of_body(input_buffer+ body_offs); if(body_p != NULL){ - printf("We found the body:\n%.*s\n", - body_p-(input_buffer+body_offs), - input_buffer+body_offs); - + printf("Data found, interpreting...\n"); size_t body_len = body_p- (input_buffer+body_offs); - - write((fds[!i].fd), + + char* new_body = attach_files( input_buffer+body_offs, body_len); + + if(new_body != NULL){ + /* Write the replacement */ + write((fds[!i].fd), new_body, + strlen(new_body)); + free(new_body); + }else{ + /* Write the original */ + write((fds[!i].fd), + input_buffer+body_offs, + body_len); + + } + + /* Rest of conversation after message */ + write((fds[!i].fd), input_buffer+body_offs+body_len, in_len-(body_offs+body_len)); diff --git a/src/tools.c b/src/tools.c new file mode 100644 index 0000000..17b7d41 --- /dev/null +++ b/src/tools.c @@ -0,0 +1,48 @@ +/* + * tools.c - Utility functions + * The author licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "tools.h" + +#include +#include +#include + +/* Takes a string destination and inserts at the given point offset the string + * in source. Really more like a stringcat with shifting the end. + * dest_orig_len is without '\0'*/ +const char* insert_string(char * destination, const char* source, + size_t dest_orig_len, size_t offset){ + + if(source == NULL|| dest_orig_len < offset){ + return destination; + } + + size_t src_len = strlen(source); + size_t new_len = dest_orig_len + src_len + 1; + + char* result = realloc(destination, new_len); + if(result == NULL){ + /* Out of memory... Failed me.. */ + return NULL; + } + memmove(result+offset+src_len, result+offset, dest_orig_len - offset); + memcpy(result+offset, source, src_len); + return result; + + +} +