AmendHub

Download:

jcs

/

subtext

/

amendments

/

74

mail: Implement deleting and marking messages unread


jcs made amendment 74 over 2 years ago
--- mail.c Thu Feb 17 12:16:02 2022 +++ mail.c Thu Feb 17 14:50:25 2022 @@ -50,15 +50,31 @@ struct bile_object_field mail_object_fields[] = { member_size(struct private_message, parent_message_id), -1 }, }; +void mail_free_message_strings(struct private_message *msg); short mail_save(struct session *s, struct private_message *msg); size_t mail_find_for_user_id(unsigned long user_id, unsigned long **mail_ids); void mail_help(struct session *s); -short mail_read(struct session *s, unsigned long idx); +void mail_read(struct session *s, unsigned long idx); +void mail_delete(struct session *s, unsigned long idx); +void mail_mark_unread(struct session *s, unsigned long idx); void mail_list(struct session *s, bool sent, unsigned long **mail_ids, size_t *nmsgs); void +mail_free_message_strings(struct private_message *msg) +{ + if (msg->subject) { + free(msg->subject); + msg->subject = NULL; + } + if (msg->body) { + free(msg->body); + msg->body = NULL; + } +} + +void mail_menu(struct session *s) { char arg[32]; @@ -93,6 +109,12 @@ mail_menu(struct session *s) if (sscanf(field, "c %s%n", &arg, &count) == 1 && count > 1) mail_compose(s, arg, NULL, NULL); + else if (strcmp(field, "c") == 0) + mail_compose(s, NULL, NULL, NULL); + else if (sscanf(field, "d %ld%n", &id, &count) == 1 && count > 1) + mail_delete(s, id); + else if (sscanf(field, "u %ld%n", &id, &count) == 1 && count > 1) + mail_mark_unread(s, id); else if (sscanf(field, "%ld%n", &id, &count) == 1 && count > 1) { if (id < 1 || id > nmsgs) { session_output_string(s, "Invalid message id\r\n"); @@ -100,13 +122,12 @@ mail_menu(struct session *s) continue; } mail_read(s, mail_ids[id - 1]); - } else if (strcmp(field, "c") == 0) - mail_compose(s, NULL, NULL, NULL); + } else if (strcmp(field, "l") == 0) mail_list(s, false, &mail_ids, &nmsgs); - else if (strcmp(field, "q") == 0) + else if (strcmp(field, "q") == 0 || strcmp(field, "x") == 0) done = true; - else if (strcmp(field, "?") == 0) + else if (strcmp(field, "?") == 0 || strcmp(field, "h") == 0) mail_help(s); else if (field[0] != '\0') { session_output_template(s, @@ -122,9 +143,12 @@ void mail_help(struct session *s) { session_output_template(s, - "({{B}}L{{/}})ist and read mail messages\r\n" - "({{B}}C{{/}})ompose new message\r\n" - "({{B}}Q{{/}})uit to main menu\r\n"); + "{{B}}l{{/}}: List mail messages\r\n" + "{{B}}#{{/}}: Read mail message [#]\r\n" + "{{B}}d #{{/}}: Delete mail message [#]\r\n" + "{{B}}u #{{/}}: Mark mail message [#] unread\r\n" + "{{B}}c{{/}}: Compose new mail message\r\n" + "{{B}}q{{/}}: Return to main menu\r\n"); session_flush(s); } @@ -274,10 +298,7 @@ mail_compose_start: mail_compose_done: if (to_username) free(to_username); - if (msg.subject) - free(msg.subject); - if (msg.body) - free(msg.body); + mail_free_message_strings(&msg); } void @@ -320,15 +341,12 @@ mail_list(struct session *s, bool sent, unsigned long msg.read ? "" : ansi(s, ANSI_RESET, ANSI_END)); session_flush(s); - if (msg.subject) - free(msg.subject); - if (msg.body) - free(msg.body); + mail_free_message_strings(&msg); free(data); } } -short +void mail_read(struct session *s, unsigned long id) { char time[32]; @@ -359,16 +377,71 @@ mail_read(struct session *s, unsigned long id) if (!msg.read) { msg.read = Time; - mail_save(s, &msg); + if (mail_save(s, &msg) != 0) + session_output_string(s, "Failed marking message read!\r\n"); } - if (msg.subject) - free(msg.subject); - if (msg.body) - free(msg.body); + mail_free_message_strings(&msg); free(data); } +void +mail_delete(struct session *s, unsigned long idx) +{ + unsigned long *mail_ids; + size_t nmsgs; + + nmsgs = mail_find_for_user_id(s->user->id, &mail_ids); + if (idx > nmsgs) { + session_printf(s, "Invalid message id {{B}}%ld{{/}}\r\n", idx); + goto delete_done; + } + + if (bile_delete(db->bile, DB_MESSAGE_RTYPE, mail_ids[idx - 1]) == 0) + session_printf(s, "Deleted message {{B}}%ld{{/}}\r\n", idx); + else + session_printf(s, "Failed deleting message {{B}}%ld{{/}}! " + "(%d)\r\n", idx, bile_error(db->bile)); + +delete_done: + if (mail_ids) + free(mail_ids); +} + +void +mail_mark_unread(struct session *s, unsigned long idx) +{ + struct private_message msg; + unsigned long *mail_ids; + size_t nmsgs, size; + char *data; + + nmsgs = mail_find_for_user_id(s->user->id, &mail_ids); + if (idx > nmsgs) { + session_printf(s, "Invalid message id {{B}}%ld{{/}}\r\n", idx); + goto unread_done; + } + + size = bile_read_alloc(db->bile, DB_MESSAGE_RTYPE, mail_ids[idx - 1], + &data); + bile_unmarshall_object(db->bile, mail_object_fields, + nitems(mail_object_fields), data, size, &msg); + msg.read = 0; + if (mail_save(s, &msg) == 0) + session_printf(s, "Marked message {{B}}%ld{{/}} unread\r\n", + idx); + else + session_printf(s, "Failed marking message {{B}}%ld{{/}} " + "unread!\r\n", idx); + + mail_free_message_strings(&msg); + free(data); + +unread_done: + if (mail_ids) + free(mail_ids); +} + short mail_save(struct session *s, struct private_message *msg) { @@ -386,7 +459,13 @@ mail_save(struct session *s, struct private_message *m return -1; } - bile_write(db->bile, DB_MESSAGE_RTYPE, msg->id, data, size); + if (bile_write(db->bile, DB_MESSAGE_RTYPE, msg->id, data, + size) != size) { + warn("mail_save: bile_write failed! %d", bile_error(db->bile)); + return bile_error(db->bile); + } + + return 0; } size_t