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

Annotation of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations)
Fri Aug 24 17:42:49 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.4: +51 -9 lines
File MIME type: text/plain
Printing of an info message and other small changes

1 lefcha 1.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 lefcha 1.4 extern int curacc;
22     extern account_data **accounts;
23 lefcha 1.1 extern int options;
24    
25    
26     /*
27     * Connects to mailserver.
28     */
29 lefcha 1.5 int establish_connection(void)
30 lefcha 1.1 {
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 lefcha 1.4 if (!(hostinfo = gethostbyname(accounts[curacc]->server))) {
43 lefcha 1.1 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 lefcha 1.4 name.sin_port = htons(accounts[curacc]->port);
50 lefcha 1.1 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 lefcha 1.4 verbose("Connected to %s.\n", hostinfo->h_name);
59 lefcha 1.1
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 lefcha 1.2 int r;
124     unsigned int saveopt;
125 lefcha 1.1 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 lefcha 1.5 * Proccesses the data that server sent due to IMAP SELSECT client request.
140     */
141     int select_response(void)
142     {
143     int r, i, s;
144     char buf[RESPONSE_BUFFER_MAX];
145     char exists[SELECT_RESULTS_MAX], recent[SELECT_RESULTS_MAX];
146     regex_t compexp[2];
147     regmatch_t match[2];
148     const char *reg[2] = {
149     "\\* ([[:digit:]]+) EXISTS",
150     "\\* ([[:digit:]]+) RECENT"
151     };
152    
153     r = get_response(buf);
154    
155     for (i = 0; i < 2; i++)
156     regcomp(&compexp[i], reg[i], REG_EXTENDED);
157    
158     if (!regexec(&compexp[0], buf, 2, match, 0)) {
159     s = min(match[1].rm_eo - match[1].rm_so, SELECT_RESULTS_MAX - 1);
160     strncpy(exists, buf + match[1].rm_so, s);
161     exists[s] = 0;
162     } else
163     exists[0] = 0;
164    
165     if (!regexec(&compexp[1], buf, 2, match, 0)) {
166     s = min(match[1].rm_eo - match[1].rm_so, SELECT_RESULTS_MAX - 1);
167     strncpy(recent, buf + match[1].rm_so, s);
168     recent[s] = 0;
169     } else
170     recent[0] = 0;
171    
172     if (!(options & OPTION_DETAILS_QUITE))
173     printf("%s messages exist, %s of which recent.\n", exists, recent);
174    
175     return r;
176     }
177    
178    
179     /*
180 lefcha 1.2 * Processes the data that server sent due to IMAP SEARCH client request.
181 lefcha 1.1 */
182     int search_response(char *results)
183     {
184 lefcha 1.5 int r, s, len;
185 lefcha 1.1 char buf[RESPONSE_BUFFER_MAX];
186     regex_t compexp;
187     regmatch_t match[2];
188 lefcha 1.3 const char *reg = "\\* SEARCH([[:digit:] ]*)";
189    
190     len = strlen(results);
191 lefcha 1.1
192 lefcha 1.5 r = get_response(buf);
193 lefcha 1.1
194     regcomp(&compexp, reg, REG_EXTENDED);
195    
196     if (!regexec(&compexp, buf, 2, match, 0)) {
197     s = min(match[1].rm_eo - match[1].rm_so, SEARCH_RESULTS_MAX - 1);
198 lefcha 1.3 strncpy(results + len, buf + match[1].rm_so, s);
199     results[s + len] = 0;
200 lefcha 1.5 }
201     return r;
202 lefcha 1.1 }
203    
204    
205     /*
206 lefcha 1.2 * Processes the data that server sent due to IMAP FETCH client request.
207 lefcha 1.1 */
208 lefcha 1.5 int fetch_response(char *results)
209 lefcha 1.1 {
210 lefcha 1.5 int r, i, s, len = 0;
211 lefcha 1.1 char buf[RESPONSE_BUFFER_MAX];
212     regex_t compexp[3];
213     regmatch_t match[1];
214     const char *reg[3] = {
215     "Date: [[:print:]]*",
216     "From: [[:print:]]*",
217     "Subject: [[:print:]]*"
218     };
219    
220 lefcha 1.5 r = get_response(buf);
221 lefcha 1.1
222     for (i = 0; i < 3; i++) {
223     regcomp(&compexp[i], reg[i], REG_EXTENDED);
224    
225     if (!regexec(&compexp[i], buf, 1, match, 0)) {
226     s = min(match[0].rm_eo - match[0].rm_so,
227     HEADERS_MAX - len - 1);
228     strncpy(results + len, buf + match[0].rm_so, s);
229     results[s + len] = '\n';
230     results[s + len + 1] = 0;
231     len = strlen(results);
232     }
233     }
234 lefcha 1.5
235     return r;
236 lefcha 1.1 }
237    
238    
239     /*
240     * Checks if response of server to client's request was succesfully
241     * delivered or there was some kind of error.
242     */
243     void analyze_response(char *buf)
244     {
245     int s;
246     regex_t compexp;
247     regmatch_t match[2];
248     const char *reg = "[[:xdigit:]]{4,4} ([[:print:]]*)";
249     char response[RESPONSE_BUFFER_MAX];
250    
251     regcomp(&compexp, reg, REG_EXTENDED);
252    
253     if (!regexec(&compexp, buf, 2, match, 0)) {
254     s = min(match[1].rm_eo - match[1].rm_so, RESPONSE_BUFFER_MAX - 1);
255     strncpy(response, buf + match[1].rm_so, s);
256     response[s] = 0;
257     printf("Server response: %s\n", response);
258     }
259     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26