1 #ifndef MANAGESIEVE_CLIENT_H
2 #define MANAGESIEVE_CLIENT_H
3 
4 #include "managesieve-commands.h"
5 
6 struct client;
7 struct sieve_storage;
8 struct managesieve_parser;
9 struct managesieve_arg;
10 
11 struct client_command_context {
12 	struct client *client;
13 	struct event *event;
14 
15 	pool_t pool;
16 	/* Name of this command */
17 	const char *name;
18 	/* Parameters for this command. These are generated from parsed
19 	   ManageSieve arguments, so they may not be exactly the same as how
20 	   client sent them. */
21 	const char *args;
22 
23 	command_func_t *func;
24 	void *context;
25 
26 	bool param_error:1;
27 };
28 
29 struct managesieve_module_register {
30 	unsigned int id;
31 };
32 
33 union managesieve_module_context {
34 	struct managesieve_module_register *reg;
35 };
36 extern struct managesieve_module_register managesieve_module_register;
37 
38 struct client {
39 	struct client *prev, *next;
40 
41 	struct event *event;
42 	const char *session_id;
43 	int fd_in, fd_out;
44 	struct io *io;
45 	struct istream *input;
46 	struct ostream *output;
47 	struct timeout *to_idle, *to_idle_output;
48 
49 	pool_t pool;
50 	struct mail_storage_service_user *service_user;
51 	const struct managesieve_settings *set;
52 
53 	struct mail_user *user;
54 
55 	struct sieve_instance *svinst;
56 	struct sieve_storage *storage;
57 
58 	time_t last_input, last_output;
59 	unsigned int bad_counter;
60 
61 	struct managesieve_parser *parser;
62 	struct client_command_context cmd;
63 
64 	uoff_t put_bytes;
65 	uoff_t get_bytes;
66 	uoff_t check_bytes;
67 	unsigned int put_count;
68 	unsigned int get_count;
69 	unsigned int check_count;
70 	unsigned int deleted_count;
71 	unsigned int renamed_count;
72 
73 	bool disconnected:1;
74 	bool destroyed:1;
75 	bool command_pending:1;
76 	bool input_pending:1;
77 	bool output_pending:1;
78 	bool handling_input:1;
79 	bool anvil_sent:1;
80 	bool input_skip_line:1; /* skip all the data until we've found a new
81 	                           line */
82 };
83 
84 extern struct client *managesieve_clients;
85 extern unsigned int managesieve_client_count;
86 
87 /* Create new client with specified input/output handles. socket specifies
88    if the handle is a socket. */
89 struct client *
90 client_create(int fd_in, int fd_out, const char *session_id,
91 	      struct event *event, struct mail_user *user,
92 	      struct mail_storage_service_user *service_user,
93 	      const struct managesieve_settings *set);
94 void client_create_finish(struct client *client);
95 void client_destroy(struct client *client, const char *reason);
96 
97 void client_dump_capability(struct client *client);
98 
99 /* Disconnect client connection */
100 void client_disconnect(struct client *client, const char *reason);
101 void client_disconnect_with_error(struct client *client, const char *msg);
102 
103 /* Send a line of data to client. Returns 1 if ok, 0 if buffer is getting full,
104    -1 if error */
105 int client_send_line(struct client *client, const char *data);
106 
107 void client_send_response(struct client *client, const char *oknobye,
108 			  const char *resp_code, const char *msg);
109 
110 #define client_send_ok(client, msg) \
111 	client_send_response(client, "OK", NULL, msg)
112 #define client_send_no(client, msg) \
113 	client_send_response(client, "NO", NULL, msg)
114 #define client_send_bye(client, msg) \
115 	client_send_response(client, "BYE", NULL, msg)
116 
117 #define client_send_okresp(client, resp_code, msg) \
118 	client_send_response(client, "OK", resp_code, msg)
119 #define client_send_noresp(client, resp_code, msg) \
120 	client_send_response(client, "NO", resp_code, msg)
121 #define client_send_byeresp(cmd, resp_code, msg) \
122 	client_send_response(client, "BYE", resp_code, msg)
123 
124 struct event_passthrough *
125 client_command_create_finish_event(struct client_command_context *cmd);
126 
127 /* Send BAD command error to client. msg can be NULL. */
128 void client_send_command_error(struct client_command_context *cmd,
129 			       const char *msg);
130 
131 /* Send storage or sieve-related errors to the client. Returns command finish
132    event with the "error" field set accordingly. */
133 void client_command_storage_error(struct client_command_context *cmd,
134 				  const char *source_filename,
135 				  unsigned int source_linenum,
136 				  const char *log_prefix, ...)
137 				  ATTR_FORMAT(4, 5);
138 #define client_command_storage_error(cmd, ...) \
139 	client_command_storage_error(cmd, __FILE__, __LINE__, __VA_ARGS__)
140 
141 /* Read a number of arguments. Returns TRUE if everything was read or
142    FALSE if either needs more data or error occurred. */
143 bool client_read_args(struct client_command_context *cmd, unsigned int count,
144 		      unsigned int flags, bool no_more,
145 		      const struct managesieve_arg **args_r);
146 /* Reads a number of string arguments. ... is a list of pointers where to
147    store the arguments. */
148 bool client_read_string_args(struct client_command_context *cmd, bool no_more,
149 			     unsigned int count, ...);
150 
client_read_no_args(struct client_command_context * cmd)151 static inline bool client_read_no_args(struct client_command_context *cmd)
152 {
153 	return client_read_args(cmd, 0, 0, TRUE, NULL);
154 }
155 
156 void _client_reset_command(struct client *client);
157 void client_input(struct client *client);
158 int client_output(struct client *client);
159 
160 void clients_destroy_all(void);
161 
162 #endif
163