Revision bump
[mmondor.git] / mmsoftware / mmmail / src / mmpop3d / mmpop3d.h
1 /* $Id: mmpop3d.h,v 1.29 2009/01/17 03:48:20 mmondor Exp $ */
2
3 /*
4 * Copyright (C) 2001-2008, Matthew Mondor
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software written by Matthew Mondor.
18 * 4. The name of Matthew Mondor may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 * 5. Redistribution of source code may not be released under the terms of
22 * any GNU Public License derivate.
23 *
24 * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36
37
38
39 #ifndef MMPOP3D_H
40 #define MMPOP3D_H
41
42
43
44
45 /* HEADERS */
46
47 #include <sys/types.h>
48 #include <stdbool.h>
49 #include <stdint.h>
50
51 #include <pthread.h>
52
53 #include <mmtypes.h>
54 #include <mmhash.h>
55 #include <mmpool.h>
56 #include <mmserver.h>
57 #include <mmlist.h>
58 #include <mmfd.h>
59 #include <mmstat.h>
60
61 #include <mm_pthread_sleep.h>
62
63 #include <libpq-fe.h>
64
65
66
67
68 /* DEFINITIONS */
69
70 #define DAEMON_NAME "mmpop3d"
71 #define DAEMON_VERSION "mmmail-0.3.2/mmondor"
72
73 /* Negative states are used by the state swapper, others are real states */
74 #define STATE_ERROR -3
75 #define STATE_END -2
76 #define STATE_CURRENT -1
77 #define STATE_AUTH 0
78 #define STATE_MAIN 1
79
80 /* Asynchroneous functions we attach */
81 #define ASYNC_CHECKPW 1
82
83 /* Error registration macro */
84 #define REGISTER_ERROR(x) do { \
85 (x)->errors++; \
86 if (CONF.DELAY_ON_ERROR) \
87 pthread_sleep((x)->errors); \
88 } while (/* CONSTCOND */0)
89
90
91
92
93 /* STRUCTURES */
94
95 /* We store config file read results in this structure */
96 typedef struct config {
97 char LOCK_PATH[256], CHROOT_DIR[256], PID_PATH[256], USER[32], GROUPS[256],
98 LOG_FACILITY[32], LISTEN_IPS[1024], SERVER_NAMES[1024], DB_INFO[1024],
99 MAIL_DIR[256];
100 long ALLOC_BUFFERS, LOG_LEVEL, LISTEN_PORT, MAX_ERRORS, MAX_IPS,
101 MAX_PER_IP, CONNECTION_RATE, CONNECTION_PERIOD, INPUT_TIMEOUT,
102 BANDWIDTH_IN, BANDWIDTH_OUT, GBANDWIDTH_IN, GBANDWIDTH_OUT,
103 ASYNC_PROCESSES;
104 bool RESOLVE_HOSTS, DELAY_ON_ERROR, STATFAIL_LOGIN, STATFAIL_PASSWORD;
105 } CONFIG;
106
107 /* For the messages list during the session */
108 typedef struct msgnode {
109 char id[24]; /* ID in the database */
110 char file[256]; /* Fullpath to message file */
111 char h_from[64], h_to[64], h_subject[64]; /* Headers preview */
112 long size; /* Message size in bytes */
113 bool retreived, deleted, read; /* Flags */
114 } msgnode;
115
116 /* For a loaded message body */
117 typedef struct msgdata {
118 void *internal;
119 char *body;
120 size_t size;
121 } msgdata;
122
123 /* A user environment, one copy per connected client exists */
124 typedef struct clientenv {
125 pnode_t node;
126 fdbuf *fdb; /* Buffered handler around our fd */
127 char *buffer; /* Buffer that points to last command line */
128 char *c_hostname; /* Pointer to client's hostname */
129 char *c_ipaddr; /* Pointer to client's IP address string */
130 char *mailbox; /* Mailbox, this is if USER was specified */
131 msgnode *index; /* Available messages with flags */
132 long size; /* Size of total messages in index */
133 long newsize; /* Current size of undeleted messages */
134 long messages; /* Number of messages, to know index size */
135 long newmessages; /* Current number of messages after deleted */
136 long last; /* Last message read in current session */
137 long errors; /* Total number of errors that occured */
138 int timeout; /* Timeout in ms */
139 unsigned long id; /* Our connection ID */
140 unsigned long retreived, deleted; /* Number of msgs retrieved & deleted */
141 bool login; /* For all_quit() */
142 struct iface *iface; /* Current interface user connected through */
143 struct async_clenv *aclenv; /* Thread context for async_call() */
144 mmstat_t vstat, pstat; /* Persistent mmstat(3) handles */
145 PGconn *pgconn; /* Persistent db connection */
146 } clientenv;
147
148 /* Used for mmfd thread support delegation/abstraction */
149 struct mutexnode {
150 pnode_t node;
151 pthread_mutex_t mutex;
152 };
153
154 /* This defines a state */
155 typedef struct state {
156 int (**functions)(clientenv *);
157 int errcode;
158 char *errtext;
159 } state;
160
161 /* A command of a state */
162 typedef struct command {
163 int loglevel;
164 char *name;
165 } command;
166
167 /* Used for fast command lookup */
168 struct commandnode {
169 hashnode_t node;
170 uint32_t hash;
171 int index;
172 struct command *command;
173 };
174
175 /* Used by our asynchoneous functions */
176 struct async_checkpw_msg {
177 struct async_msg msg;
178 union {
179 struct {
180 bool matching;
181 } res;
182 struct {
183 char hash[48];
184 char passwd[256];
185 } args;
186 } un;
187 };
188
189
190
191
192 /* PROTOTYPES */
193
194 int main(int, char **);
195
196 static int all_noop(clientenv *);
197 static int all_quit(clientenv *);
198 static int all_beer(clientenv *);
199 static int auth_user(clientenv *);
200 static int auth_pass(clientenv *);
201 static int main_rset(clientenv *);
202 static int main_stat(clientenv *);
203 static int main_list(clientenv *);
204 static int main_retr(clientenv *);
205 static int main_dele(clientenv *);
206 static int main_last(clientenv *);
207 static int main_top(clientenv *);
208 static int main_uidl(clientenv *);
209 static int main_head(clientenv *);
210 static int main_page(clientenv *);
211
212 static int lock_check(const char *);
213 static bool hash_commands(struct command *, size_t);
214 static uint32_t commandnode_keyhash(const void *, size_t);
215 static int commandnode_keycmp(const void *, const void *, size_t);
216 static bool do_buildindex(clientenv *);
217 static bool do_message_load(msgdata *, msgnode *);
218 static void do_message_free(msgdata *);
219 static bool do_retreive(fdbuf *, msgnode *);
220 static bool do_top(fdbuf *, msgnode *, long);
221 static bool do_page(fdbuf *, msgnode *, long, long);
222 static bool do_update(clientenv *);
223 static bool msgwrite(fdbuf *, const void *, size_t);
224 static bool reply(fdbuf *, bool, const char *, ...);
225 static bool clenv_constructor(pnode_t *);
226 static void clenv_destructor(pnode_t *);
227 static void *utdata_constructor(void);
228 static void utdata_destructor(void *);
229 static clientenv *alloc_clientenv(void);
230 static bool init_clientenv(clientenv *);
231 static clientenv *free_clientenv(clientenv *);
232 static bool valid_address(char *, char *);
233 static bool valid_host(char *);
234 inline static bool valid_char(char);
235
236 static int handleclient(unsigned long, int, clientlistnode *, struct iface *,
237 struct async_clenv *, void *);
238
239 static void thread_init(void);
240 static void *thread_mutex_create(void);
241 static void *thread_mutex_destroy(void *);
242 static void thread_mutex_lock(void *);
243 static void thread_mutex_unlock(void *);
244 static bool thread_eintr(void);
245
246 static void async_checkpw(struct async_msg *);
247 static bool checkpw(clientenv *, const char *, const char *);
248
249
250
251
252 #endif