Implemented mail removal

Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
Tyrolyean 2020-04-30 21:12:29 +02:00
parent 7e51aedc5b
commit e9a42139ef
No known key found for this signature in database
GPG key ID: 81EC9BAC5E9667C6
5 changed files with 100 additions and 2 deletions

View file

@ -71,6 +71,8 @@ struct email_t{
int append_header(struct email_t* mail, const char* key, const char* value);
int append_to_header(struct email_t* mail, const char* pair);
int remove_mail(struct email_t* mail);
struct email_t* get_root_mail(struct email_t* mail);
void propagate_insert_delete(struct email_t* mail, char* change_p,

View file

@ -24,6 +24,8 @@
char* insert_string(char * destination, const char* source,
size_t dest_orig_len, size_t offset);
void remove_string(char * string, size_t len, size_t offset, size_t remove);
char* search_header_key(const struct email_t* mail, const char* key);
char* get_value_from_key(size_t* val_len, size_t key_offset,
@ -36,4 +38,7 @@ const char* get_next_line(const char* message, size_t len);
const char* get_prev_line(const char* message, size_t len_neg);
bool detect_base64(const struct email_t* mail);
void propagate_size_change(struct email_t *mail, ssize_t change);
#endif /* TOOLS_H */

View file

@ -358,9 +358,15 @@ int replace_base64_files(struct email_t* mail, const char* dirname){
}
}
/* Replace the mail message with some html text TODO */
/* Delete old attachment */
if(mail->parent != NULL){
if(remove_mail(mail) < 0){
fprintf(stderr, "Failed to remove old attachment!!\n");
return -1;
}
}
return 0;
}

View file

@ -76,7 +76,7 @@ int append_to_header(struct email_t* mail, const char* pair){
if(new_root == NULL){
return -1;
}
mail->message_length += strlen(buffer);
propagate_size_change(mail, strlen(buffer));
propagate_root_pointer(root, new_root, old_root);
propagate_insert_delete(root, root->message+root_offset,
@ -89,6 +89,60 @@ int append_to_header(struct email_t* mail, const char* pair){
}
int remove_mail(struct email_t* mail){
if(mail == NULL || mail->parent == NULL || !mail->parent->is_multipart){
return -1;
}
struct email_t* parent = mail->parent;
bool found = false;
for(size_t i = 0; i < parent->submes_cnt; i++){
if(parent->submes[i] == mail){
/* Remove ourselfs from the parent */
found = true;
}
if(found && (i+1 < parent->submes_cnt)){
parent->submes[i] = parent->submes[i+1];
}
}
if(!found){
return -1;
}
parent->submes_cnt--;
/* Find the boundary that should come after our content */
char * after_boundary =
strstr(mail->message+mail->message_length, parent->boundary);
if(after_boundary == NULL){
return -1;
}
const char * end = get_next_line(after_boundary,
parent->message_length-(after_boundary - parent->message));
if(end == NULL){
end = parent->message + parent->message_length;
}
size_t remove_len = mail->message - end;
struct email_t *root = get_root_mail(mail);
if(root == NULL){
return -1;
}
size_t remove_offset = mail->message - root->message;
remove_string(root->message, root->message_length,
remove_offset, remove_len);
propagate_size_change(mail, -remove_len);
propagate_insert_delete(root, mail->message+remove_offset, -remove_len);
return 0;
}
struct email_t* get_root_mail(struct email_t* mail){
if(mail == NULL){

View file

@ -49,6 +49,19 @@ char* insert_string(char * destination, const char* source,
}
/* Takes a string string and removes from offset INCLUDING the character there
* the following remove bytes. Len is without the NULL-termination
*/
void remove_string(char * string, size_t len, size_t offset, size_t remove){
memmove(string+offset, string+offset+remove, len - (offset+remove));
string[len-remove] = 0;
return;
}
/* Searches the given header for the key provided and, if found, returns the
* pointer to that key NOT the value
*/
@ -186,3 +199,21 @@ const char* get_prev_line(const char* message, size_t len_neg){
return NULL;
}
/* Propagates a size change inside the body UP. This only alters the complete
* BODY length, the header len remains untouched. A positive change tells that
* something was added, a negative one that something was removed. Call this
* from the object you modified.
*/
void propagate_size_change(struct email_t *mail, ssize_t change){
if(mail == NULL){
return;
}
mail->message_length += change;
if(mail->parent != NULL){
propagate_size_change(mail->parent, change);
}
return;
}