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

Contents of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Mon Aug 20 21:40:57 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.2: +6 -4 lines
File MIME type: text/plain
Added message size limits support

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 int sock;
21 extern account_data account;
22 extern int options;
23
24
25 /*
26 * Connects to mailserver.
27 */
28 int establish_connection()
29 {
30 struct sockaddr_in name;
31 struct hostent *hostinfo;
32
33 memset((char *) &name, 0, sizeof(struct sockaddr_in));
34
35 sock = socket(PF_INET, SOCK_STREAM, 0);
36 if (sock < 0) {
37 error("imapfilter: create socket; %s\n", strerror(errno));
38 return FAILURE;
39 }
40
41 if (!(hostinfo = gethostbyname(account.server))) {
42 error("imapfilter: get network host entry; %s\n", strerror(errno));
43 close_connection();
44 return FAILURE;
45 }
46
47 name.sin_family = AF_INET;
48 name.sin_port = htons(account.port);
49 name.sin_addr = *(struct in_addr *) hostinfo->h_addr;
50
51 if (connect(sock, (struct sockaddr *) &name, sizeof(struct sockaddr))) {
52 error("imapfilter: initiating connection; %s\n", strerror(errno));
53 close_connection();
54 return FAILURE;
55 }
56
57 verbose("Connected to %s.\n", hostinfo->h_name, account.port);
58
59 return SUCCESS;
60 }
61
62
63 /*
64 * Disconnects from mailserver.
65 */
66 int close_connection(void)
67 {
68 if (close(sock)) {
69 error("imapfilter: closing socket; %s\n", strerror(errno));
70 return FAILURE;
71 } else {
72 return SUCCESS;
73 }
74 }
75
76
77 /*
78 * Reads (if any) data the server sent.
79 */
80 int get_response(char *buf)
81 {
82 int flags;
83 fd_set rfds;
84 struct timeval tv;
85
86 memset(buf, 0, RESPONSE_BUFFER_MAX);
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_BUFFER_MAX - 1) != -1) {
100 #ifdef DEBUG
101 printf("\n%s\n", buf);
102 #endif
103 if (options & OPTION_DETAILS_VERBOSE)
104 analyze_response(buf);
105
106 fcntl(sock, F_SETFL, flags);
107 return SUCCESS;
108 }
109 }
110
111 fcntl(sock, F_SETFL, flags);
112
113 return FAILURE;
114 }
115
116
117 /*
118 * Clears stream from any data server sent without processing them.
119 */
120 int clear_stream(void)
121 {
122 int r;
123 unsigned int saveopt;
124 char buf[RESPONSE_BUFFER_MAX];
125
126 saveopt = options; /* Needed so response won't be analyzed. */
127 options &= OPTION_DETAILS_CLEAR;
128
129 r = get_response(buf);
130
131 options = saveopt;
132
133 return r;
134 }
135
136
137 /*
138 * Processes the data that server sent due to IMAP SEARCH client request.
139 */
140 int search_response(char *results)
141 {
142 int s, len;
143 char buf[RESPONSE_BUFFER_MAX];
144 regex_t compexp;
145 regmatch_t match[2];
146 const char *reg = "\\* SEARCH([[:digit:] ]*)";
147
148 len = strlen(results);
149
150 get_response(buf);
151
152 regcomp(&compexp, reg, REG_EXTENDED);
153
154 if (!regexec(&compexp, buf, 2, match, 0)) {
155 s = min(match[1].rm_eo - match[1].rm_so, SEARCH_RESULTS_MAX - 1);
156 strncpy(results + len, buf + match[1].rm_so, s);
157 results[s + len] = 0;
158 return SUCCESS;
159 } else
160 return FAILURE;
161 }
162
163
164 /*
165 * Processes the data that server sent due to IMAP FETCH client request.
166 */
167 void fetch_response(char *results)
168 {
169 int i, s, len = 0;
170 char buf[RESPONSE_BUFFER_MAX];
171 regex_t compexp[3];
172 regmatch_t match[1];
173 const char *reg[3] = {
174 "Date: [[:print:]]*",
175 "From: [[:print:]]*",
176 "Subject: [[:print:]]*"
177 };
178
179 get_response(buf);
180
181 for (i = 0; i < 3; i++) {
182 regcomp(&compexp[i], reg[i], REG_EXTENDED);
183
184 if (!regexec(&compexp[i], buf, 1, match, 0)) {
185 s = min(match[0].rm_eo - match[0].rm_so,
186 HEADERS_MAX - len - 1);
187 strncpy(results + len, buf + match[0].rm_so, s);
188 results[s + len] = '\n';
189 results[s + len + 1] = 0;
190 len = strlen(results);
191 }
192 }
193 }
194
195
196 /*
197 * Checks if response of server to client's request was succesfully
198 * delivered or there was some kind of error.
199 */
200 void analyze_response(char *buf)
201 {
202 int s;
203 regex_t compexp;
204 regmatch_t match[2];
205 const char *reg = "[[:xdigit:]]{4,4} ([[:print:]]*)";
206 char response[RESPONSE_BUFFER_MAX];
207
208 regcomp(&compexp, reg, REG_EXTENDED);
209
210 if (!regexec(&compexp, buf, 2, match, 0)) {
211 s = min(match[1].rm_eo - match[1].rm_so, RESPONSE_BUFFER_MAX - 1);
212 strncpy(response, buf + match[1].rm_so, s);
213 response[s] = 0;
214 printf("Server response: %s\n", response);
215 }
216 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26