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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations)
Thu Oct 4 14:19:31 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
Changes since 1.6: +5 -6 lines
File MIME type: text/plain
Small changes.

1 lefcha 1.1 #include <stdio.h>
2     #include <unistd.h>
3     #include <stdlib.h>
4 lefcha 1.4 #include <errno.h>
5 lefcha 1.1 #include <string.h>
6     #include <fcntl.h>
7     #include <sys/time.h>
8     #include <sys/types.h>
9     #include <regex.h>
10    
11    
12     #include "config.h"
13     #include "imapfilter.h"
14    
15    
16     extern int sock;
17     extern unsigned int options;
18    
19    
20     /*
21 lefcha 1.3 * Read data the server sent.
22 lefcha 1.1 */
23     int receive_response(char *buf)
24     {
25     int flags;
26     fd_set fds;
27     struct timeval tv;
28    
29     memset(buf, 0, RESPONSE_BUF);
30    
31 lefcha 1.2 tv.tv_sec = 20;
32 lefcha 1.1 tv.tv_usec = 0;
33    
34     flags = fcntl(sock, F_GETFL, 0);
35     fcntl(sock, F_SETFL, flags | O_NONBLOCK);
36    
37     FD_ZERO(&fds);
38     FD_SET(sock, &fds);
39    
40     if ((select(sock + 1, &fds, NULL, NULL, &tv) > 0)
41     && FD_ISSET(sock, &fds)) {
42     if (read(sock, buf, RESPONSE_BUF - 1) != -1) {
43     #ifdef DEBUG
44     printf("\n%s\n", buf);
45     #endif
46     fcntl(sock, F_SETFL, flags);
47    
48     return analyze_response(buf);
49     }
50     }
51 lefcha 1.6 fcntl(sock, F_SETFL, flags);
52 lefcha 1.1
53 lefcha 1.4 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
54     strerror(errno));
55 lefcha 1.6
56 lefcha 1.4 return ERROR_NETWORK;
57 lefcha 1.1 }
58    
59    
60     /*
61     * Get server response to client's request.
62     */
63 lefcha 1.4 int server_response(char *cmd)
64 lefcha 1.1 {
65 lefcha 1.4 int r;
66 lefcha 1.1 char buf[RESPONSE_BUF];
67 lefcha 1.6
68 lefcha 1.4 do
69     r = receive_response(buf);
70     while (*cmd && !strstr(buf, cmd));
71 lefcha 1.6
72 lefcha 1.4 return r;
73 lefcha 1.1 }
74    
75    
76     /*
77 lefcha 1.3 * Process the data that server sent due to IMAP STATUS client request.
78 lefcha 1.1 */
79     int status_response(void)
80     {
81     int r;
82     char buf[RESPONSE_BUF];
83     unsigned int exist, recent, unseen;
84    
85     exist = recent = unseen = 0;
86    
87     do
88     r = receive_response(buf);
89     while (!strstr(buf, "STATUS"));
90    
91     sscanf(buf, "* STATUS %*s (MESSAGES %d RECENT %d UNSEEN %d)", &exist,
92     &recent, &unseen);
93    
94 lefcha 1.6 info(" %d messages exist, %d recent, %d unseen.\n", exist, recent,
95 lefcha 1.1 unseen);
96    
97     return r;
98     }
99    
100    
101     /*
102 lefcha 1.3 * Process the data that server sent due to IMAP SEARCH client request.
103 lefcha 1.1 */
104     int search_response(char *mesgs)
105     {
106     int r;
107     char buf[RESPONSE_BUF];
108    
109     do
110     r = receive_response(buf);
111     while (!strstr(buf, "SEARCH"));
112    
113     sscanf(buf, "* SEARCH %511[0-9 ]", mesgs);
114    
115     return r;
116     }
117    
118    
119     /*
120 lefcha 1.3 * Process the data that server sent due to IMAP FETCH client request.
121 lefcha 1.1 */
122 lefcha 1.4 int fetch_response(void)
123 lefcha 1.1 {
124     int r, s, i;
125     char buf[RESPONSE_BUF];
126     char *pos;
127 lefcha 1.4 char headers[HEADERS_BUF];
128 lefcha 1.6
129 lefcha 1.4 headers[0] = 0;
130 lefcha 1.6
131 lefcha 1.1 do
132     r = receive_response(buf);
133     while (!strstr(buf, "FETCH"));
134 lefcha 1.6
135 lefcha 1.4 pos = buf;
136 lefcha 1.1
137 lefcha 1.6 while ((pos = strchr(pos, '{'))) {
138 lefcha 1.4 s = atoi(pos + 1);
139     pos = strchr(pos, '}');
140 lefcha 1.7
141 lefcha 1.4 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
142     headers[i] = *(pos + 3 + i);
143 lefcha 1.6
144 lefcha 1.4 headers[i] = 0;
145 lefcha 1.6
146 lefcha 1.7 if (*headers) {
147     if (options & OPTION_HEADERS)
148     info("%s\n", headers);
149 lefcha 1.6 log_info(LOG_WRITE, headers);
150 lefcha 1.7 } else
151 lefcha 1.6 log_info(LOG_WRITE, NULL);
152 lefcha 1.4 }
153 lefcha 1.6
154 lefcha 1.1 return r;
155     }
156    
157    
158     /*
159 lefcha 1.3 * Process the data that server sent due to IMAP COPY client request.
160 lefcha 1.1 */
161     int copy_response(void)
162     {
163     int r;
164     char buf[RESPONSE_BUF];
165    
166     do
167     r = receive_response(buf);
168     while (!strstr(buf, "COPY"));
169    
170     if (r == 1 && strstr(buf, "[TRYCREATE]"))
171     return 1;
172    
173     return 0;
174     }
175    
176    
177     /*
178 lefcha 1.3 * Check if response of server to client's request was succesfully
179 lefcha 1.1 * delivered or there was some kind of error.
180     */
181     int analyze_response(char *buf)
182     {
183 lefcha 1.4 int r = 0;
184 lefcha 1.1 regex_t creg;
185     regmatch_t match[3];
186 lefcha 1.4 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD) [[:print:]]+)\r\n";
187 lefcha 1.1 char result[RESULT_BUF];
188    
189 lefcha 1.4 result[0] = 0;
190    
191 lefcha 1.1 regcomp(&creg, reg, REG_EXTENDED);
192 lefcha 1.6
193 lefcha 1.1 if (!regexec(&creg, buf, 3, match, 0)) {
194 lefcha 1.4 strncat(result, buf + match[1].rm_so,
195     min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
196 lefcha 1.1
197     if (!strncmp(buf + match[2].rm_so, "NO", 2))
198     r = 1;
199     else if (!strncmp(buf + match[2].rm_so, "BAD", 3))
200     r = -1;
201 lefcha 1.6
202 lefcha 1.1 verbose("Server response: %s\n", result);
203     }
204 lefcha 1.6 regfree(&creg);
205 lefcha 1.1
206     return r;
207     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26