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

Contents of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Thu Aug 23 19:13:15 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.3: +5 -4 lines
File MIME type: text/plain
Added support for more than one accounts

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26