/[imapfilter]/imapfilter/connect.c
ViewVC logotype

Contents of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Tue Aug 28 22:42:06 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.9: +38 -0 lines
File MIME type: text/plain
Info message about deleted mails.

1 #include <stdio.h>
2 #include <errno.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/time.h>
6 #include <sys/socket.h>
7 #include <fcntl.h>
8 #include <netdb.h>
9 #include <netinet/in.h>
10 #include <string.h>
11 #include <regex.h>
12
13 #include "config.h"
14 #include "imapfilter.h"
15 #include "connect.h"
16 #include "log.h"
17 #include "imap.h"
18
19
20 extern account_t *accounts;
21 extern unsigned int options;
22
23 int sock;
24
25
26 /*
27 * Connects to mailserver.
28 */
29 int init_connection(account_t * ca)
30 {
31 struct sockaddr_in name;
32 struct hostent *hostinfo;
33
34 memset((char *) &name, 0, sizeof(struct sockaddr_in));
35
36 sock = socket(PF_INET, SOCK_STREAM, 0);
37 if (sock < 0) {
38 error("imapfilter: create socket; %s\n", strerror(errno));
39 return 1;
40 }
41
42 if (!(hostinfo = gethostbyname(ca->server))) {
43 error("imapfilter: get network host entry; %s\n", strerror(errno));
44 close_connection();
45 return 1;
46 }
47
48 name.sin_family = AF_INET;
49 name.sin_port = htons(ca->port);
50 name.sin_addr = *(struct in_addr *) hostinfo->h_addr;
51
52 if (connect(sock, (struct sockaddr *) &name, sizeof(struct sockaddr))) {
53 error("imapfilter: initiating connection; %s\n", strerror(errno));
54 close_connection();
55 return 1;
56 }
57
58 info("Connected to %s as %s.\n", hostinfo->h_name, ca->userid);
59
60 return 0;
61 }
62
63
64 /*
65 * Disconnects from mailserver.
66 */
67 int close_connection(void)
68 {
69 if (close(sock)) {
70 error("imapfilter: closing socket; %s\n", strerror(errno));
71 return 1;
72 } else
73 return 0;
74 }
75
76
77 /*
78 * Reads data the server sent.
79 */
80 int recv_response(char *buf)
81 {
82 int flags;
83 fd_set rfds;
84 struct timeval tv;
85
86 memset(buf, 0, RESPONSE_BUF);
87
88 tv.tv_sec = 10;
89 tv.tv_usec = 0;
90
91 flags = fcntl(sock, F_GETFL, 0);
92 fcntl(sock, F_SETFL, flags | O_NONBLOCK);
93
94 FD_ZERO(&rfds);
95 FD_SET(sock, &rfds);
96
97 if ((select(sock + 1, &rfds, NULL, NULL, &tv) > 0)
98 && FD_ISSET(sock, &rfds)) {
99 if (read(sock, buf, RESPONSE_BUF - 1) != -1) {
100 #ifdef DEBUG
101 printf("\n%s\n", buf);
102 #endif
103 if (options & OPT_DETAILS_VERBOSE)
104 analyze_response(buf);
105
106 fcntl(sock, F_SETFL, flags);
107 return 0;
108 }
109 }
110
111 fcntl(sock, F_SETFL, flags);
112
113 return 1;
114 }
115
116
117 /*
118 * Clears stream from any data server sent.
119 */
120 int clear_stream(void)
121 {
122 char buf[RESPONSE_BUF];
123
124 return recv_response(buf);
125 }
126
127
128 /*
129 * Processes the data that server sent due to IMAP STATUS client request.
130 */
131 int status_response(void)
132 {
133 int r, s;
134 char buf[RESPONSE_BUF];
135 char exist[STATUS_BUF], recent[STATUS_BUF], unseen[STATUS_BUF];
136 regex_t creg;
137 regmatch_t match[4];
138 const char *reg =
139 "\\* STATUS INBOX \\(MESSAGES ([[:digit:]]+) RECENT ([[:digit:]]+) UNSEEN ([[:digit:]]+)\\)";
140
141 exist[0] = recent[0] = unseen[0] = 0;
142
143 r = recv_response(buf);
144
145 regcomp(&creg, reg, REG_EXTENDED);
146
147 if (!regexec(&creg, buf, 4, match, 0)) {
148 s = min(match[1].rm_eo - match[1].rm_so, STATUS_BUF - 1);
149 strncpy(exist, buf + match[1].rm_so, s);
150 exist[s] = 0;
151
152 s = min(match[2].rm_eo - match[2].rm_so, STATUS_BUF - 1);
153 strncpy(recent, buf + match[2].rm_so, s);
154 recent[s] = 0;
155
156 s = min(match[3].rm_eo - match[3].rm_so, STATUS_BUF - 1);
157 strncpy(unseen, buf + match[3].rm_so, s);
158 unseen[s] = 0;
159
160 info("%s messages exist, %s recent, %s unseen.\n", exist, recent,
161 unseen);
162 }
163
164 regfree(&creg);
165
166 return r;
167 }
168
169
170 /*
171 * Processes the data that server sent due to IMAP SEARCH client request.
172 */
173 int search_response(char *res)
174 {
175 int r, s, len;
176 char buf[RESPONSE_BUF];
177 regex_t creg;
178 regmatch_t match[2];
179 const char *reg = "\\* SEARCH([[:digit:] ]*)";
180
181 len = strlen(res);
182
183 r = recv_response(buf);
184
185 regcomp(&creg, reg, REG_EXTENDED);
186
187 if (!regexec(&creg, buf, 2, match, 0)) {
188 s = min(match[1].rm_eo - match[1].rm_so, SEARCH_BUF - 1);
189 strncpy(res + len, buf + match[1].rm_so, s);
190 res[s + len] = 0;
191 }
192
193 regfree(&creg);
194
195 return r;
196 }
197
198
199 /*
200 * Processes the data that server sent due to IMAP FETCH client request.
201 */
202 int fetch_response(char *res)
203 {
204 int r, i, s, len = 0;
205 char buf[RESPONSE_BUF];
206 regex_t creg[3];
207 regmatch_t match[1];
208 const char *reg[3] = {
209 "Date: [[:print:]]*",
210 "From: [[:print:]]*",
211 "Subject: [[:print:]]*"
212 };
213
214 r = recv_response(buf);
215
216 for (i = 0; i < 3; i++) {
217 regcomp(&creg[i], reg[i], REG_EXTENDED);
218
219 if (!regexec(&creg[i], buf, 1, match, 0)) {
220 s = min(match[0].rm_eo - match[0].rm_so,
221 HEADERS_MAX - len - 1);
222 strncpy(res + len, buf + match[0].rm_so, s);
223 res[s + len] = '\n';
224 res[s + len + 1] = 0;
225 len = strlen(res);
226 }
227 }
228
229 for (i = 0; i < 3; i++)
230 regfree(&creg[i]);
231
232 return r;
233 }
234
235
236 /*
237 * Proccesses data that server sent due to IMAP EXPUNGE client request.
238 */
239 int expunge_response(void)
240 {
241 int r, i = 0, e = 0;
242 char buf[RESPONSE_BUF];
243 regex_t creg;
244 regmatch_t match[1];
245 const char *reg = "\\* [[:digit:]]+ EXPUNGE";
246
247 r = recv_response(buf);
248
249 regcomp(&creg, reg, REG_EXTENDED);
250
251 while (!regexec(&creg, buf + e, 1, match, 0)) {
252 e += match[0].rm_eo;
253 i++;
254 }
255
256 info("%d messages expunged.\n", i);
257
258 regfree(&creg);
259
260 return r;
261 }
262
263
264 /*
265 * Checks if response of server to client's request was succesfully
266 * delivered or there was some kind of error.
267 */
268 void analyze_response(char *buf)
269 {
270 int s;
271 regex_t creg;
272 regmatch_t match[2];
273 const char *reg = "[[:xdigit:]]{4,4} ((OK|NO|BAD) [[:print:]]*)";
274 char res[RESULTS_BUF];
275
276 regcomp(&creg, reg, REG_EXTENDED);
277
278 if (!regexec(&creg, buf, 2, match, 0)) {
279 s = min(match[1].rm_eo - match[1].rm_so, RESULTS_BUF - 1);
280 strncpy(res, buf + match[1].rm_so, s);
281 res[s] = 0;
282 printf("Server response: %s\n", res);
283 }
284
285 regfree(&creg);
286 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26