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

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations)
Thu Oct 4 15:48:34 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
Changes since 1.7: +6 -2 lines
File MIME type: text/plain
Better phrasing of info messages.

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 if (!exist) {
95 info("No messages ");
96 return -2;
97 }
98 info("%d message%s, %d recent, %d unseen, ", exist, plural(exist), recent,
99 unseen);
100
101 return r;
102 }
103
104
105 /*
106 * Process the data that server sent due to IMAP SEARCH client request.
107 */
108 int search_response(char *mesgs)
109 {
110 int r;
111 char buf[RESPONSE_BUF];
112
113 do
114 r = receive_response(buf);
115 while (!strstr(buf, "SEARCH"));
116
117 sscanf(buf, "* SEARCH %511[0-9 ]", mesgs);
118
119 return r;
120 }
121
122
123 /*
124 * Process the data that server sent due to IMAP FETCH client request.
125 */
126 int fetch_response(void)
127 {
128 int r, s, i;
129 char buf[RESPONSE_BUF];
130 char *pos;
131 char headers[HEADERS_BUF];
132
133 headers[0] = 0;
134
135 do
136 r = receive_response(buf);
137 while (!strstr(buf, "FETCH"));
138
139 pos = buf;
140
141 while ((pos = strchr(pos, '{'))) {
142 s = atoi(pos + 1);
143 pos = strchr(pos, '}');
144
145 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
146 headers[i] = *(pos + 3 + i);
147
148 headers[i] = 0;
149
150 if (*headers) {
151 if (options & OPTION_HEADERS)
152 info("%s\n", headers);
153 log_info(LOG_WRITE, headers);
154 } else
155 log_info(LOG_WRITE, NULL);
156 }
157
158 return r;
159 }
160
161
162 /*
163 * Process the data that server sent due to IMAP COPY client request.
164 */
165 int copy_response(void)
166 {
167 int r;
168 char buf[RESPONSE_BUF];
169
170 do
171 r = receive_response(buf);
172 while (!strstr(buf, "COPY"));
173
174 if (r == 1 && strstr(buf, "[TRYCREATE]"))
175 return 1;
176
177 return 0;
178 }
179
180
181 /*
182 * Check if response of server to client's request was succesfully
183 * delivered or there was some kind of error.
184 */
185 int analyze_response(char *buf)
186 {
187 int r = 0;
188 regex_t creg;
189 regmatch_t match[3];
190 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD) [[:print:]]+)\r\n";
191 char result[RESULT_BUF];
192
193 result[0] = 0;
194
195 regcomp(&creg, reg, REG_EXTENDED);
196
197 if (!regexec(&creg, buf, 3, match, 0)) {
198 strncat(result, buf + match[1].rm_so,
199 min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
200
201 if (!strncmp(buf + match[2].rm_so, "NO", 2))
202 r = 1;
203 else if (!strncmp(buf + match[2].rm_so, "BAD", 3))
204 r = -1;
205
206 verbose("Server response: %s\n", result);
207 }
208 regfree(&creg);
209
210 return r;
211 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26