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

Annotation of /imapfilter/connect.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sun Aug 12 16:06:45 2001 UTC (22 years, 8 months ago) by lefcha
Branch: MAIN
Changes since 1.1: +4 -5 lines
File MIME type: text/plain
Merged small changes from v0.1.1

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     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 lefcha 1.2 int r;
123     unsigned int saveopt;
124 lefcha 1.1 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 lefcha 1.2 * Processes the data that server sent due to IMAP SEARCH client request.
139 lefcha 1.1 */
140     int search_response(char *results)
141     {
142     int s;
143     char buf[RESPONSE_BUFFER_MAX];
144     regex_t compexp;
145     regmatch_t match[2];
146     const char *reg = "\\* SEARCH ([[:digit:] ]*)";
147    
148     get_response(buf);
149    
150     regcomp(&compexp, reg, REG_EXTENDED);
151    
152     if (!regexec(&compexp, buf, 2, match, 0)) {
153     s = min(match[1].rm_eo - match[1].rm_so, SEARCH_RESULTS_MAX - 1);
154     strncpy(results, buf + match[1].rm_so, s);
155     results[s] = 0;
156     return SUCCESS;
157     } else
158     return FAILURE;
159     }
160    
161    
162     /*
163 lefcha 1.2 * Processes the data that server sent due to IMAP FETCH client request.
164 lefcha 1.1 */
165     void fetch_response(char *results)
166     {
167     int i, s, len = 0;
168     char buf[RESPONSE_BUFFER_MAX];
169     regex_t compexp[3];
170     regmatch_t match[1];
171     const char *reg[3] = {
172     "Date: [[:print:]]*",
173     "From: [[:print:]]*",
174     "Subject: [[:print:]]*"
175     };
176    
177     get_response(buf);
178    
179     for (i = 0; i < 3; i++) {
180     regcomp(&compexp[i], reg[i], REG_EXTENDED);
181    
182     if (!regexec(&compexp[i], buf, 1, match, 0)) {
183     s = min(match[0].rm_eo - match[0].rm_so,
184     HEADERS_MAX - len - 1);
185     strncpy(results + len, buf + match[0].rm_so, s);
186     results[s + len] = '\n';
187     results[s + len + 1] = 0;
188     len = strlen(results);
189     }
190     }
191     }
192    
193    
194     /*
195     * Checks if response of server to client's request was succesfully
196     * delivered or there was some kind of error.
197     */
198     void analyze_response(char *buf)
199     {
200     int s;
201     regex_t compexp;
202     regmatch_t match[2];
203     const char *reg = "[[:xdigit:]]{4,4} ([[:print:]]*)";
204     char response[RESPONSE_BUFFER_MAX];
205    
206     regcomp(&compexp, reg, REG_EXTENDED);
207    
208     if (!regexec(&compexp, buf, 2, match, 0)) {
209     s = min(match[1].rm_eo - match[1].rm_so, RESPONSE_BUFFER_MAX - 1);
210     strncpy(response, buf + match[1].rm_so, s);
211     response[s] = 0;
212     printf("Server response: %s\n", response);
213     }
214     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26