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

Diff of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by lefcha, Fri Nov 2 01:13:48 2001 UTC revision 1.13 by lefcha, Tue Nov 6 17:41:27 2001 UTC
# Line 14  Line 14 
14    
15  extern unsigned int options;  extern unsigned int options;
16    
17    static char *packet = NULL;     /* Pointer to dynamically allocated packet
18                                       buffer. */
19    static unsigned long pms = 0;   /* Current memory size of packet. */
20    
21    
22  /*  /*
23   * Read data the server sent.   * Allocate initial ammount of memory for the packet.
24   */   */
25  int receive_response(char *buf)  void packet_alloc(void)
26  {  {
27      socket_read(buf);      if (packet)
28            return;
29    
30        packet = (char *) xmalloc(PACKET_SIZE + 1);
31        packet[0] = 0;
32    
33        pms = PACKET_SIZE;
34    
35  #ifdef DEBUG  #ifdef DEBUG
36      printf("\n%s\n", buf);      printf("debug: packet memory size: %lu\n", pms);
37  #endif  #endif
38    }
39    
40    
41    /*
42     * Reallocate more memory for the packet.
43     */
44    void packet_realloc(void)
45    {
46        if (strlen(packet) >= pms - SOCKET_READ_BUF) {
47            packet = (char *) xrealloc(packet, pms + PACKET_SIZE + 1);
48    
49            pms += PACKET_SIZE;
50    
51    #ifdef DEBUG
52            printf("debug: packet memory size: %lu\n", pms);
53    #endif
54        }
55    }
56    
57      return analyze_response(buf);  
58    /*
59     * Prepare the packet space for a new server response to arrive.
60     */
61    void packet_clear(void)
62    {
63        packet[0] = 0;
64    }
65    
66    
67    
68    /*
69     * Read one data fragment, server's response, and put it to concatenate to
70     * packet.
71     */
72    void receive_response(void)
73    {
74        packet_alloc();
75        packet_realloc();
76    
77        socket_read(packet);
78  }  }
79    
80    
# Line 35  int receive_response(char *buf) Line 83  int receive_response(char *buf)
83   */   */
84  int server_response(unsigned int tag)  int server_response(unsigned int tag)
85  {  {
86      int r;      packet_clear();
     char buf[RESPONSE_BUF];  
87    
88      do      do
89          r = receive_response(buf);          receive_response();
90      while (tag && !strcasestr(buf, ultostr(tag, 16)));      while (tag && !strcasestr(packet, ultostr(tag, 16)));
91    
92    #ifdef DEBUG
93        printf("\n%s\n", packet);
94    #endif
95    
96      return r;      return analyze_response();
97  }  }
98    
99    
# Line 51  int server_response(unsigned int tag) Line 102  int server_response(unsigned int tag)
102   */   */
103  int greeting_response(void)  int greeting_response(void)
104  {  {
105      char buf[RESPONSE_BUF];      receive_response();
106    
107      receive_response(buf);  #ifdef DEBUG
108        printf("\n%s\n", packet);
109    #endif
110    
111      if (strcasestr(buf, "BYE"))      if (strcasestr(packet, "BYE"))
112          return RESPONSE_BYE;          return RESPONSE_BYE;
113    
114      return RESPONSE_OK;      return RESPONSE_OK;
115  }  }
116    
117    
118  /*  /*
119   * Process the data that server sent due to IMAP CAPABILITY client request.   * Process the data that server sent due to IMAP CAPABILITY client request.
120   */   */
121  int capability_response(unsigned int tag)  int capability_response(unsigned int tag)
122  {  {
123      int r;      packet_clear();
     char buf[RESPONSE_BUF];  
124    
125      do      do
126          r = receive_response(buf);          receive_response();
127      while (!strcasestr(buf, ultostr(tag, 16)));      while (!strcasestr(packet, ultostr(tag, 16)));
128    
129    #ifdef DEBUG
130        printf("\n%s\n", packet);
131    #endif
132    
133      if (!strcasestr(buf, "IMAP4rev1")) {      if (!strcasestr(packet, "IMAP4rev1")) {
134          error("imapfilter: server does not support IMAP4rev1 protocol\n");          error("imapfilter: server does not support IMAP4rev1 protocol\n");
135          return -2;          return -2;
136      }      }
137      return r;      return analyze_response();
138  }  }
139    
140    
# Line 86  int capability_response(unsigned int tag Line 143  int capability_response(unsigned int tag
143   */   */
144  int status_response(unsigned int tag)  int status_response(unsigned int tag)
145  {  {
     int r;  
     char buf[RESPONSE_BUF];  
146      unsigned int exist, recent, unseen;      unsigned int exist, recent, unseen;
147      char *c;      char *c;
148    
149        packet_clear();
150    
151      exist = recent = unseen = 0;      exist = recent = unseen = 0;
152    
153      do      do {
154          r = receive_response(buf);          receive_response();
155      while (!strcasestr(buf, ultostr(tag, 16)));      } while (!strcasestr(packet, ultostr(tag, 16)));
156    
157      if ((c = strcasestr(buf, "MESSAGES"))) {  #ifdef DEBUG
158        printf("\n%s\n", packet);
159    #endif
160    
161        if ((c = strcasestr(packet, "MESSAGES"))) {
162          c += 9;          c += 9;
163          exist = strtoul(c, NULL, 10);          exist = strtoul(c, NULL, 10);
164      }      }
165      if ((c = strcasestr(buf, "RECENT"))) {      if ((c = strcasestr(packet, "RECENT"))) {
166          c += 7;          c += 7;
167          recent = strtoul(c, NULL, 10);          recent = strtoul(c, NULL, 10);
168      }      }
169      if ((c = strcasestr(buf, "UNSEEN"))) {      if ((c = strcasestr(packet, "UNSEEN"))) {
170          c += 7;          c += 7;
171          unseen = strtoul(c, NULL, 10);          unseen = strtoul(c, NULL, 10);
172      }      }
# Line 116  int status_response(unsigned int tag) Line 177  int status_response(unsigned int tag)
177      info("%d message%s, %d recent, %d unseen, ", exist, plural(exist),      info("%d message%s, %d recent, %d unseen, ", exist, plural(exist),
178           recent, unseen);           recent, unseen);
179    
180      return r;      return analyze_response();
181  }  }
182    
183    
# Line 125  int status_response(unsigned int tag) Line 186  int status_response(unsigned int tag)
186   */   */
187  int select_response(unsigned int tag)  int select_response(unsigned int tag)
188  {  {
189      int r;      packet_clear();
     char buf[RESPONSE_BUF];  
190    
191      do      do
192          r = receive_response(buf);          receive_response();
193      while (!strcasestr(buf, ultostr(tag, 16)));      while (!strcasestr(packet, ultostr(tag, 16)));
194    
195      if (strcasestr(buf, "[READ-ONLY]"))  #ifdef DEBUG
196        printf("\n%s\n", packet);
197    #endif
198    
199        if (strcasestr(packet, "[READ-ONLY]"))
200          return RESPONSE_READONLY;          return RESPONSE_READONLY;
201    
202      return r;      return analyze_response();
203  }  }
204    
205    
206  /*  /*
207   * Process the data that server sent due to IMAP SEARCH client request.   * Process the data that server sent due to IMAP SEARCH client request.
208   */   */
209  int search_response(unsigned int tag, char *mesgs)  int search_response(unsigned int tag, char **mesgs)
210  {  {
211      int r;      int cnt = -1;
212      char buf[RESPONSE_BUF];      char *c, *m;
     char *c, *m = mesgs;  
213    
214      do      packet_clear();
         r = receive_response(buf);  
     while (!strcasestr(buf, ultostr(tag, 16)));  
215    
216      if ((c = strcasestr(buf, "SEARCH "))) {      do {
217            receive_response();
218            cnt++;
219        } while (!strcasestr(packet + cnt * SOCKET_READ_BUF, ultostr(tag, 16)));
220    
221    #ifdef DEBUG
222        printf("\n%s\n", packet);
223    #endif
224    
225        *mesgs = (char *) xmalloc(strlen(packet));
226    
227        m = *mesgs;
228    
229        if ((c = strcasestr(packet, "SEARCH "))) {
230          c += 7;          c += 7;
231          while (m - mesgs < SEARCH_MESSAGES_BUF && (isdigit(*c) || *c == ' '))          while (isdigit(*c) || *c == ' ')
232              *(m++) = *(c++);              *(m++) = *(c++);
         if (m - mesgs == SEARCH_MESSAGES_BUF)  
             *(strrchr(mesgs, ' ')) = 0;  
         else  
             *m = 0;  
233      }      }
234            *m = 0;
235      return r;  
236        return analyze_response();
237  }  }
238    
239    
# Line 171  int search_response(unsigned int tag, ch Line 242  int search_response(unsigned int tag, ch
242   */   */
243  int fetch_response(unsigned int tag)  int fetch_response(unsigned int tag)
244  {  {
245      int r, s, i;      int s, i, cnt = -1;
     char buf[RESPONSE_BUF];  
246      char *pos;      char *pos;
247      char headers[HEADERS_BUF];      char headers[HEADERS_BUF];
248    
249      headers[0] = 0;      packet[0] = headers[0] = 0;
250    
251      do      do {
252          r = receive_response(buf);          receive_response();
253      while (!strcasestr(buf, ultostr(tag, 16)));          cnt++;
254        } while (!strcasestr(packet + cnt * SOCKET_READ_BUF, ultostr(tag, 16)));
255    
256    #ifdef DEBUG
257        printf("\n%s\n", packet);
258    #endif
259    
260      pos = buf;      pos = packet;
261    
262      while ((pos = strchr(pos, '{'))) {      while ((pos = strchr(pos, '{'))) {
263          s = atoi(pos + 1);          s = atoi(pos + 1);
# Line 202  int fetch_response(unsigned int tag) Line 277  int fetch_response(unsigned int tag)
277              log_info(LOG_WRITE, NULL);              log_info(LOG_WRITE, NULL);
278      }      }
279    
280      return r;      return analyze_response();
281  }  }
282    
283    
# Line 211  int fetch_response(unsigned int tag) Line 286  int fetch_response(unsigned int tag)
286   */   */
287  int copy_response(unsigned int tag)  int copy_response(unsigned int tag)
288  {  {
289      int r;      packet_clear();
     char buf[RESPONSE_BUF];  
290    
291      do      do
292          r = receive_response(buf);          receive_response();
293      while (!strcasestr(buf, ultostr(tag, 16)));      while (!strcasestr(packet, ultostr(tag, 16)));
294    
295    #ifdef DEBUG
296        printf("\n%s\n", packet);
297    #endif
298    
299      if (r == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))      if (analyze_response() == RESPONSE_NO && strcasestr(packet, "[TRYCREATE]"))
300          return RESPONSE_TRYCREATE;          return RESPONSE_TRYCREATE;
301    
302      return RESPONSE_OK;      return RESPONSE_OK;
# Line 229  int copy_response(unsigned int tag) Line 307  int copy_response(unsigned int tag)
307   * Check if response of server to client's request was succesfully   * Check if response of server to client's request was succesfully
308   * delivered or there was some kind of error.   * delivered or there was some kind of error.
309   */   */
310  int analyze_response(char *buf)  int analyze_response(void)
311  {  {
312      int r = RESPONSE_OK;      int r = RESPONSE_OK;
313      regex_t creg;      regex_t creg;
314      regmatch_t match[3];      regmatch_t match[3];
315      const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";      const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
316      char result[RESULT_BUF];      char result[RESPONSE_BUF];
317    
318      result[0] = 0;      result[0] = 0;
319    
320      regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);      regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
321    
322      if (!regexec(&creg, buf, 3, match, 0)) {      if (!regexec(&creg, packet, 3, match, 0)) {
323          strncat(result, buf + match[1].rm_so,          strncat(result, packet + match[1].rm_so,
324                  min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));                  min(match[1].rm_eo - match[1].rm_so, RESPONSE_BUF - 1));
325    
326          if (!strncasecmp(buf + match[2].rm_so, "NO", 2))          if (!strncasecmp(packet + match[2].rm_so, "NO", 2))
327              r = RESPONSE_NO;              r = RESPONSE_NO;
328          else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))          else if (!strncasecmp(packet + match[2].rm_so, "BAD", 3))
329              r = RESPONSE_BAD;              r = RESPONSE_BAD;
330    
331          verbose("Server response: %s\n", result);          verbose("Server response: %s\n", result);

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26