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

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show 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 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #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 * Read data the server sent.
22 */
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 tv.tv_sec = 20;
32 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 fcntl(sock, F_SETFL, flags);
52
53 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
54 strerror(errno));
55
56 return ERROR_NETWORK;
57 }
58
59
60 /*
61 * Get server response to client's request.
62 */
63 int server_response(char *cmd)
64 {
65 int r;
66 char buf[RESPONSE_BUF];
67
68 do
69 r = receive_response(buf);
70 while (*cmd && !strstr(buf, cmd));
71
72 return r;
73 }
74
75
76 /*
77 * Process the data that server sent due to IMAP STATUS client request.
78 */
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 info(" %d messages exist, %d recent, %d unseen.\n", exist, recent,
95 unseen);
96
97 return r;
98 }
99
100
101 /*
102 * Process the data that server sent due to IMAP SEARCH client request.
103 */
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 * Process the data that server sent due to IMAP FETCH client request.
121 */
122 int fetch_response(void)
123 {
124 int r, s, i;
125 char buf[RESPONSE_BUF];
126 char *pos;
127 char headers[HEADERS_BUF];
128
129 headers[0] = 0;
130
131 do
132 r = receive_response(buf);
133 while (!strstr(buf, "FETCH"));
134
135 pos = buf;
136
137 while ((pos = strchr(pos, '{'))) {
138 s = atoi(pos + 1);
139 pos = strchr(pos, '}');
140
141 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
142 headers[i] = *(pos + 3 + i);
143
144 headers[i] = 0;
145
146 if (*headers) {
147 if (options & OPTION_HEADERS)
148 info("%s\n", headers);
149 log_info(LOG_WRITE, headers);
150 } else
151 log_info(LOG_WRITE, NULL);
152 }
153
154 return r;
155 }
156
157
158 /*
159 * Process the data that server sent due to IMAP COPY client request.
160 */
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 * Check if response of server to client's request was succesfully
179 * delivered or there was some kind of error.
180 */
181 int analyze_response(char *buf)
182 {
183 int r = 0;
184 regex_t creg;
185 regmatch_t match[3];
186 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD) [[:print:]]+)\r\n";
187 char result[RESULT_BUF];
188
189 result[0] = 0;
190
191 regcomp(&creg, reg, REG_EXTENDED);
192
193 if (!regexec(&creg, buf, 3, match, 0)) {
194 strncat(result, buf + match[1].rm_so,
195 min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
196
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
202 verbose("Server response: %s\n", result);
203 }
204 regfree(&creg);
205
206 return r;
207 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26