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

Annotation of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations)
Sun Aug 26 01:18:24 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.5: +62 -63 lines
File MIME type: text/plain
Structural 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 lefcha 1.6 extern account_t *accounts;
21     extern int options;
22    
23 lefcha 1.1 int sock;
24    
25    
26     /*
27     * Connects to mailserver.
28     */
29 lefcha 1.6 int init_connection(account_t * ca)
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 lefcha 1.6 return 1;
40 lefcha 1.1 }
41    
42 lefcha 1.6 if (!(hostinfo = gethostbyname(ca->server))) {
43 lefcha 1.1 error("imapfilter: get network host entry; %s\n", strerror(errno));
44     close_connection();
45 lefcha 1.6 return 1;
46 lefcha 1.1 }
47    
48     name.sin_family = AF_INET;
49 lefcha 1.6 name.sin_port = htons(ca->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 lefcha 1.6 return 1;
56 lefcha 1.1 }
57    
58 lefcha 1.4 verbose("Connected to %s.\n", hostinfo->h_name);
59 lefcha 1.1
60 lefcha 1.6 return 0;
61 lefcha 1.1 }
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 lefcha 1.6 return 1;
72     } else
73     return 0;
74 lefcha 1.1 }
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 lefcha 1.6 memset(buf, 0, RESPONSE_BUF);
87 lefcha 1.1
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 lefcha 1.6 if (read(sock, buf, RESPONSE_BUF - 1) != -1) {
100 lefcha 1.1 #ifdef DEBUG
101     printf("\n%s\n", buf);
102     #endif
103 lefcha 1.6 if (options & OPT_DETAILS_VERBOSE)
104 lefcha 1.1 analyze_response(buf);
105    
106     fcntl(sock, F_SETFL, flags);
107 lefcha 1.6 return 0;
108 lefcha 1.1 }
109     }
110    
111     fcntl(sock, F_SETFL, flags);
112    
113 lefcha 1.6 return 1;
114 lefcha 1.1 }
115    
116    
117     /*
118     * Clears stream from any data server sent without processing them.
119     */
120     int clear_stream(void)
121     {
122 lefcha 1.2 int r;
123     unsigned int saveopt;
124 lefcha 1.6 char buf[RESPONSE_BUF];
125 lefcha 1.1
126     saveopt = options; /* Needed so response won't be analyzed. */
127 lefcha 1.6 options &= OPT_DETAILS_CLEAR;
128 lefcha 1.1
129     r = get_response(buf);
130    
131     options = saveopt;
132    
133     return r;
134     }
135    
136    
137     /*
138 lefcha 1.5 * Proccesses the data that server sent due to IMAP SELSECT client request.
139     */
140     int select_response(void)
141     {
142     int r, i, s;
143 lefcha 1.6 char buf[RESPONSE_BUF];
144     char exists[SELECT_BUF], recent[SELECT_BUF];
145     regex_t creg[2];
146 lefcha 1.5 regmatch_t match[2];
147     const char *reg[2] = {
148     "\\* ([[:digit:]]+) EXISTS",
149     "\\* ([[:digit:]]+) RECENT"
150     };
151 lefcha 1.6
152     exists[0] = recent[0] = 0;
153    
154 lefcha 1.5 r = get_response(buf);
155    
156     for (i = 0; i < 2; i++)
157 lefcha 1.6 regcomp(&creg[i], reg[i], REG_EXTENDED);
158 lefcha 1.5
159 lefcha 1.6 if (!regexec(&creg[0], buf, 2, match, 0)) {
160     s = min(match[1].rm_eo - match[1].rm_so, SELECT_BUF - 1);
161 lefcha 1.5 strncpy(exists, buf + match[1].rm_so, s);
162     exists[s] = 0;
163 lefcha 1.6 }
164    
165     if (!regexec(&creg[1], buf, 2, match, 0)) {
166     s = min(match[1].rm_eo - match[1].rm_so, SELECT_BUF - 1);
167 lefcha 1.5 strncpy(recent, buf + match[1].rm_so, s);
168     recent[s] = 0;
169 lefcha 1.6 }
170    
171     if (!(options & OPT_DETAILS_QUITE))
172 lefcha 1.5 printf("%s messages exist, %s of which recent.\n", exists, recent);
173    
174     return r;
175     }
176    
177    
178     /*
179 lefcha 1.2 * Processes the data that server sent due to IMAP SEARCH client request.
180 lefcha 1.1 */
181 lefcha 1.6 int search_response(char *res)
182 lefcha 1.1 {
183 lefcha 1.5 int r, s, len;
184 lefcha 1.6 char buf[RESPONSE_BUF];
185     regex_t creg;
186 lefcha 1.1 regmatch_t match[2];
187 lefcha 1.3 const char *reg = "\\* SEARCH([[:digit:] ]*)";
188    
189 lefcha 1.6 len = strlen(res);
190 lefcha 1.1
191 lefcha 1.5 r = get_response(buf);
192 lefcha 1.1
193 lefcha 1.6 regcomp(&creg, reg, REG_EXTENDED);
194 lefcha 1.1
195 lefcha 1.6 if (!regexec(&creg, buf, 2, match, 0)) {
196     s = min(match[1].rm_eo - match[1].rm_so, SEARCH_BUF - 1);
197     strncpy(res + len, buf + match[1].rm_so, s);
198     res[s + len] = 0;
199 lefcha 1.5 }
200     return r;
201 lefcha 1.1 }
202    
203    
204     /*
205 lefcha 1.2 * Processes the data that server sent due to IMAP FETCH client request.
206 lefcha 1.1 */
207 lefcha 1.6 int fetch_response(char *res)
208 lefcha 1.1 {
209 lefcha 1.5 int r, i, s, len = 0;
210 lefcha 1.6 char buf[RESPONSE_BUF];
211     regex_t creg[3];
212 lefcha 1.1 regmatch_t match[1];
213     const char *reg[3] = {
214     "Date: [[:print:]]*",
215     "From: [[:print:]]*",
216     "Subject: [[:print:]]*"
217     };
218    
219 lefcha 1.5 r = get_response(buf);
220 lefcha 1.1
221     for (i = 0; i < 3; i++) {
222 lefcha 1.6 regcomp(&creg[i], reg[i], REG_EXTENDED);
223 lefcha 1.1
224 lefcha 1.6 if (!regexec(&creg[i], buf, 1, match, 0)) {
225 lefcha 1.1 s = min(match[0].rm_eo - match[0].rm_so,
226     HEADERS_MAX - len - 1);
227 lefcha 1.6 strncpy(res + len, buf + match[0].rm_so, s);
228     res[s + len] = '\n';
229     res[s + len + 1] = 0;
230     len = strlen(res);
231 lefcha 1.1 }
232     }
233 lefcha 1.5
234     return r;
235 lefcha 1.1 }
236    
237    
238     /*
239     * Checks if response of server to client's request was succesfully
240     * delivered or there was some kind of error.
241     */
242     void analyze_response(char *buf)
243     {
244     int s;
245 lefcha 1.6 regex_t creg;
246 lefcha 1.1 regmatch_t match[2];
247     const char *reg = "[[:xdigit:]]{4,4} ([[:print:]]*)";
248 lefcha 1.6 char res[RESULTS_BUF];
249 lefcha 1.1
250 lefcha 1.6 regcomp(&creg, reg, REG_EXTENDED);
251 lefcha 1.1
252 lefcha 1.6 if (!regexec(&creg, buf, 2, match, 0)) {
253     s = min(match[1].rm_eo - match[1].rm_so, RESULTS_BUF - 1);
254     strncpy(res, buf + match[1].rm_so, s);
255     res[s] = 0;
256     printf("Server response: %s\n", res);
257 lefcha 1.1 }
258     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26