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

Diff of /imapfilter/response.c

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

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

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26