1 /* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "array.h"
5 #include "mail-storage.h"
6 #include "mail-types.h"
7
8 #include "push-notification-drivers.h"
9 #include "push-notification-events.h"
10 #include "push-notification-event-flagsset.h"
11 #include "push-notification-txn-msg.h"
12
13
14 #define EVENT_NAME "FlagsSet"
15
16 static struct push_notification_event_flagsset_config default_config;
17
18
push_notification_event_flagsset_default_config(void)19 static void *push_notification_event_flagsset_default_config(void)
20 {
21 i_zero(&default_config);
22
23 return &default_config;
24 }
25
26 static void
push_notification_event_flagsset_debug_msg(struct push_notification_txn_event * event)27 push_notification_event_flagsset_debug_msg(
28 struct push_notification_txn_event *event)
29 {
30 struct push_notification_event_flagsset_data *data = event->data;
31 const char *keyword;
32
33 if ((data->flags_set & MAIL_ANSWERED) != 0)
34 i_debug("%s: Answered flag set", EVENT_NAME);
35 if ((data->flags_set & MAIL_FLAGGED) != 0)
36 i_debug("%s: Flagged flag set", EVENT_NAME);
37 if ((data->flags_set & MAIL_DELETED) != 0)
38 i_debug("%s: Deleted flag set", EVENT_NAME);
39 if ((data->flags_set & MAIL_SEEN) != 0)
40 i_debug("%s: Seen flag set", EVENT_NAME);
41 if ((data->flags_set & MAIL_DRAFT) != 0)
42 i_debug("%s: Draft flag set", EVENT_NAME);
43
44 array_foreach_elem(&data->keywords_set, keyword)
45 i_debug("%s: Keyword set [%s]", EVENT_NAME, keyword);
46 }
47
48 static struct push_notification_event_flagsset_data *
push_notification_event_flagsset_get_data(struct push_notification_txn * ptxn,struct push_notification_txn_msg * msg,struct push_notification_event_config * ec)49 push_notification_event_flagsset_get_data(
50 struct push_notification_txn *ptxn,
51 struct push_notification_txn_msg *msg,
52 struct push_notification_event_config *ec)
53 {
54 struct push_notification_event_flagsset_data *data;
55
56 data = push_notification_txn_msg_get_eventdata(msg, EVENT_NAME);
57 if (data == NULL) {
58 data = p_new(ptxn->pool,
59 struct push_notification_event_flagsset_data, 1);
60 data->flags_set = 0;
61 p_array_init(&data->keywords_set, ptxn->pool, 4);
62
63 push_notification_txn_msg_set_eventdata(ptxn, msg, ec, data);
64 }
65
66 return data;
67 }
68
69 static void
push_notification_event_flagsset_flags_event(struct push_notification_txn * ptxn,struct push_notification_event_config * ec,struct push_notification_txn_msg * msg,struct mail * mail,enum mail_flags old_flags)70 push_notification_event_flagsset_flags_event(
71 struct push_notification_txn *ptxn,
72 struct push_notification_event_config *ec,
73 struct push_notification_txn_msg *msg, struct mail *mail,
74 enum mail_flags old_flags)
75 {
76 struct push_notification_event_flagsset_config *config =
77 (struct push_notification_event_flagsset_config *)ec->config;
78 struct push_notification_event_flagsset_data *data;
79 enum mail_flags flag_check_always[] = {
80 MAIL_ANSWERED,
81 MAIL_DRAFT,
82 MAIL_FLAGGED
83 };
84 enum mail_flags flags, flags_set = 0;
85 unsigned int i;
86
87 flags = mail_get_flags(mail);
88
89 for (i = 0; i < N_ELEMENTS(flag_check_always); i++) {
90 if ((flags & flag_check_always[i]) != 0 &&
91 (old_flags & flag_check_always[i]) == 0)
92 flags_set |= flag_check_always[i];
93 }
94
95 if (!config->hide_deleted && (flags & MAIL_DELETED) != 0 &&
96 (old_flags & MAIL_DELETED) == 0) {
97 flags_set |= MAIL_DELETED;
98 }
99
100 if (!config->hide_seen && (flags & MAIL_SEEN) != 0 &&
101 (old_flags & MAIL_SEEN) == 0) {
102 flags_set |= MAIL_SEEN;
103 }
104
105 /* Only create data element if at least one flag was set. */
106 if (flags_set != 0) {
107 data = push_notification_event_flagsset_get_data(ptxn, msg, ec);
108 data->flags_set |= flags_set;
109 }
110 }
111
112 static void
push_notification_event_flagsset_keywords_event(struct push_notification_txn * ptxn,struct push_notification_event_config * ec,struct push_notification_txn_msg * msg,struct mail * mail,const char * const * old_keywords)113 push_notification_event_flagsset_keywords_event(
114 struct push_notification_txn *ptxn,
115 struct push_notification_event_config *ec,
116 struct push_notification_txn_msg *msg, struct mail *mail,
117 const char *const *old_keywords)
118 {
119 struct push_notification_event_flagsset_data *data;
120 const char *k, *const *keywords, *const *op;
121
122 data = push_notification_event_flagsset_get_data(ptxn, msg, ec);
123 keywords = mail_get_keywords(mail);
124
125 for (; *keywords != NULL; keywords++) {
126 for (op = old_keywords; *op != NULL; op++) {
127 if (strcmp(*keywords, *op) == 0)
128 break;
129 }
130
131 if (*op == NULL) {
132 k = p_strdup(ptxn->pool, *keywords);
133 array_push_back(&data->keywords_set, &k);
134 }
135 }
136 }
137
138 static void
push_notification_event_flagsset_free_msg(struct push_notification_txn_event * event)139 push_notification_event_flagsset_free_msg(
140 struct push_notification_txn_event *event)
141 {
142 struct push_notification_event_flagsset_data *data = event->data;
143
144 if (array_is_created(&data->keywords_set))
145 array_free(&data->keywords_set);
146 }
147
148 /* Event definition */
149
150 extern struct push_notification_event push_notification_event_flagsset;
151
152 struct push_notification_event push_notification_event_flagsset = {
153 .name = EVENT_NAME,
154 .init = {
155 .default_config =
156 push_notification_event_flagsset_default_config,
157 },
158 .msg = {
159 .debug_msg = push_notification_event_flagsset_debug_msg,
160 .free_msg = push_notification_event_flagsset_free_msg,
161 },
162 .msg_triggers = {
163 .flagchange = push_notification_event_flagsset_flags_event,
164 .keywordchange =
165 push_notification_event_flagsset_keywords_event,
166 },
167 };
168