1 #ifndef POP3_CLIENT_H
2 #define POP3_CLIENT_H
3 
4 #include "seq-range-array.h"
5 
6 struct client;
7 struct mail_storage;
8 struct mail_storage_service_ctx;
9 
10 typedef void command_func_t(struct client *client);
11 
12 #define MSGS_BITMASK_SIZE(client) \
13 	(MALLOC_ADD((client)->messages_count, (CHAR_BIT-1)) / CHAR_BIT)
14 
15 /* Stop reading input when output buffer has this many bytes. Once the buffer
16    size has dropped to half of it, start reading input again. */
17 #define POP3_OUTBUF_THROTTLE_SIZE 4096
18 
19 #define POP3_CLIENT_OUTPUT_FULL(client) \
20 	(o_stream_get_buffer_used_size((client)->output) >= POP3_OUTBUF_THROTTLE_SIZE)
21 
22 struct pop3_client_vfuncs {
23 	void (*destroy)(struct client *client, const char *reason);
24 
25 };
26 
27 /*
28    pop3_msn = 1..n in the POP3 protocol
29    msgnum = 0..n-1 = pop3_msn-1
30    seq = 1..n = mail's sequence number in lib-storage. when pop3 sort ordering
31      is used, msgnum_to_seq_map[] can be used for translation.
32 */
33 struct client {
34 	struct client *prev, *next;
35 
36 	struct pop3_client_vfuncs v;
37 
38 	int fd_in, fd_out;
39 	struct io *io;
40 	struct istream *input;
41 	struct ostream *output;
42 	struct timeout *to_idle, *to_commit;
43 
44 	command_func_t *cmd;
45 	void *cmd_context;
46 
47 	pool_t pool;
48 	struct mail_storage_service_user *service_user;
49 	struct mail_user *user;
50 	struct mail_namespace *inbox_ns;
51 	struct mailbox *mailbox;
52 	struct mailbox_transaction_context *trans;
53 	struct mail_keywords *deleted_kw;
54 
55 	struct timeout *to_session_dotlock_refresh;
56 	struct dotlock *session_dotlock;
57 
58 	time_t last_input, last_output;
59 	unsigned int bad_counter;
60 	unsigned int highest_expunged_fetch_msgnum;
61 
62 	unsigned int uid_validity;
63 	unsigned int messages_count;
64 	unsigned int deleted_count, seen_change_count;
65 	uoff_t total_size;
66 	uoff_t deleted_size;
67 	uint32_t last_seen_pop3_msn, lowest_retr_pop3_msn;
68 
69 	/* All sequences currently visible in the mailbox. */
70 	ARRAY_TYPE(seq_range) all_seqs;
71 	uint32_t highest_seq;
72 
73 	/* [msgnum] contains mail seq. anything after it has seq = msgnum+1 */
74 	uint32_t *msgnum_to_seq_map;
75 	uint32_t msgnum_to_seq_map_count;
76 
77 	uoff_t top_bytes;
78 	uoff_t retr_bytes;
79 	unsigned int top_count;
80 	unsigned int retr_count;
81 
82 	/* [msgnum] */
83 	const char **message_uidls;
84 	uoff_t *message_sizes;
85 	/* [msgnum/8] & msgnum%8 */
86 	unsigned char *deleted_bitmask;
87 	unsigned char *seen_bitmask;
88 
89 	/* settings: */
90 	const struct pop3_settings *set;
91 	const struct mail_storage_settings *mail_set;
92 	pool_t uidl_pool;
93 	enum uidl_keys uidl_keymask;
94 
95 	/* Module-specific contexts. */
96 	ARRAY(union pop3_module_context *) module_contexts;
97 
98 	bool destroyed:1;
99 	bool disconnected:1;
100 	bool deleted:1;
101 	bool waiting_input:1;
102 	bool anvil_sent:1;
103 	bool message_uidls_save:1;
104 	bool delete_success:1;
105 	bool quit_seen:1;
106 };
107 
108 struct pop3_module_register {
109 	unsigned int id;
110 };
111 
112 union pop3_module_context {
113 	struct pop3_client_vfuncs super;
114 	struct pop3_module_register *reg;
115 };
116 extern struct pop3_module_register pop3_module_register;
117 
118 extern struct client *pop3_clients;
119 extern unsigned int pop3_client_count;
120 
121 /* Create new client with specified input/output handles. socket specifies
122    if the handle is a socket. */
123 struct client *client_create(int fd_in, int fd_out,
124 			     struct mail_user *user,
125 			     struct mail_storage_service_user *service_user,
126 			     const struct pop3_settings *set);
127 void client_create_finish(struct client *client);
128 int client_init_mailbox(struct client *client, const char **error_r);
129 void client_destroy(struct client *client, const char *reason) ATTR_NULL(2);
130 
131 /* Disconnect client connection */
132 void client_disconnect(struct client *client, const char *reason);
133 
134 /* Send a line of data to client */
135 void client_send_line(struct client *client, const char *fmt, ...)
136 	ATTR_FORMAT(2, 3);
137 void client_send_storage_error(struct client *client);
138 
139 bool client_handle_input(struct client *client);
140 bool client_update_mails(struct client *client);
141 
142 void clients_destroy_all(void);
143 
144 int pop3_lock_session(struct client *client);
145 
146 #endif
147