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