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

Diff of /imapfilter/action.c

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

revision 1.2.2.6 by lefcha, Fri Feb 6 01:09:49 2004 UTC revision 1.17 by lefcha, Sun Feb 15 15:32:38 2004 UTC
# Line 6  Line 6 
6    
7  #include "config.h"  #include "config.h"
8  #include "imapfilter.h"  #include "imapfilter.h"
9    #include "filter.h"
10    
11    
12  extern conn_t connpri, connaux;  extern connection_t connpri, connaux;
13  extern unsigned int options;  extern options_t opts;
14    
15    
16  int action_delete(char *mesgs, char *args);  int action_delete(char *mesgs, char *args);
17  int action_copy(char *mbox, char *mesgs, char *destmbox, char *args);  int action_copy(char *mbox, char *mesgs, char *destmbox, char *args);
18  int action_move(char *mbox, char *mesgs, char *destmbox, char *args);  int action_move(char *mbox, char *mesgs, char *destmbox, char *args);
19  int action_rcopy(char *mbox, char *mesgs, account_t * destacc, char *destmbox, char *args);  int action_rcopy(char *mbox, char *mesgs, account_t * destacct, char *destmbox, char *args);
20  int action_rmove(char *mbox, char *mesgs, account_t * destacc, char *destmbox, char *args);  int action_rmove(char *mbox, char *mesgs, account_t * destacct, char *destmbox, char *args);
21  int action_flag(char *mesgs, unsigned int *type, unsigned int *msgflags, char *args);  int action_flag(char *mesgs, unsigned int *type, unsigned int *msgflags, char *args);
22  int action_list(char *mesgs, char *args);  int action_list(char *mesgs, char *args);
23    
24  unsigned int count_messages(char *mesgs);  unsigned int count_messages(char *mesgs);
25  char *convert_messages(char *mesgs);  char *convert_messages(char *mesgs);
26  int substitute_date(char *str);  int substitute_date(char *str);
27  void current_date(char *destmbox);  void system_date(char *destmbox);
28  void message_date(char *mesg, char *destmbox);  void message_date(char *mesg, char *destmbox);
29  void default_variables(char *mbox, char *destmbox);  void default_variables(char *mbox, char *destmbox);
30    void headers_variables(char *mesg, char *destmbox);
31    
32    
33  /*  /*
34   * Apply the appropriate action.   * Apply the appropriate action.
35   */   */
36  int  int
37  apply_action(char *mbox, char *mesgs, unsigned int *type, account_t * raccount,  apply_action(char *mbox, char *mesgs, unsigned int *type, account_t * destacct,
38      char *destmbox, unsigned int *msgflags, char *args)      char *destmbox, unsigned int *msgflags, char *args)
39  {  {
40          unsigned int cnt;          unsigned int cnt;
# Line 41  apply_action(char *mbox, char *mesgs, un Line 43  apply_action(char *mbox, char *mesgs, un
43                  return 0;                  return 0;
44    
45          log_info(LOG_ACTION, type);          log_info(LOG_ACTION, type);
46          log_info(LOG_DESTINATION_ACCOUNT, raccount->key);          log_info(LOG_DEST_ACCOUNT, destacct->key);
47          log_info(LOG_DESTINATION_MAILBOX, destmbox);          log_info(LOG_DEST_MBOX, destmbox);
48    
49          cnt = count_messages(mesgs);          cnt = count_messages(mesgs);
50    
51          switch (*type) {          switch (*type) {
52          case FILTER_ACTION_DELETE:          case ACTION_DELETE:
53                  info("%d message%s deleted.\n", cnt, plural(cnt));                  info("%d message%s deleted.\n", cnt, plural(cnt));
54                  action_delete(mesgs, args);                  action_delete(mesgs, args);
55                  break;                  break;
56          case FILTER_ACTION_COPY:          case ACTION_COPY:
57                  info("%d message%s copied from \"%s\" to mailbox \"%s\".\n",                  info("%d message%s copied from \"%s\" to mailbox \"%s\".\n",
58                      cnt, plural(cnt), mbox, destmbox);                      cnt, plural(cnt), mbox, destmbox);
59                  action_copy(mbox, mesgs, apply_namespace(destmbox,                  action_copy(mbox, mesgs, apply_namespace(destmbox,
60                          connpri.nsp.prefix, connpri.nsp.delim), args);                      connpri.ns.prefix, connpri.ns.delim), args);
61                  break;                  break;
62          case FILTER_ACTION_MOVE:          case ACTION_MOVE:
63                  info("%d message%s moved from \"%s\" to mailbox \"%s\".\n",                  info("%d message%s moved from \"%s\" to mailbox \"%s\".\n",
64                      cnt, plural(cnt), mbox, destmbox);                      cnt, plural(cnt), mbox, destmbox);
65                  action_move(mbox, mesgs, apply_namespace(destmbox,                  action_move(mbox, mesgs, apply_namespace(destmbox,
66                          connpri.nsp.prefix, connpri.nsp.delim), args);                      connpri.ns.prefix, connpri.ns.delim), args);
67                  break;                  break;
68          case FILTER_ACTION_RCOPY:          case ACTION_RCOPY:
69                  info("%d message%s copied from \"%s\" to mailbox "                  info("%d message%s copied from \"%s\" to mailbox "
70                      "\"%s\" at account %s.\n", cnt, plural(cnt),                      "\"%s\" at account %s.\n", cnt, plural(cnt), mbox,
71                      mbox, destmbox, raccount->key);                      destmbox, destacct->key);
72                  action_rcopy(mbox, mesgs, raccount, destmbox, args);                  action_rcopy(mbox, mesgs, destacct, destmbox, args);
73                  break;                  break;
74          case FILTER_ACTION_RMOVE:          case ACTION_RMOVE:
75                  info("%d message%s moved from \"%s\" to mailbox "                  info("%d message%s moved from \"%s\" to mailbox "
76                      "\"%s\" at account %s.\n", cnt, plural(cnt),                      "\"%s\" at account %s.\n", cnt, plural(cnt), mbox,
77                      mbox, destmbox, raccount->key);                      destmbox, destacct->key);
78                  action_rmove(mbox, mesgs, raccount, destmbox, args);                  action_rmove(mbox, mesgs, destacct, destmbox, args);
79                  break;                  break;
80          case FILTER_ACTION_FLAG_REPLACE:          case ACTION_FLAG_REPLACE:
81          case FILTER_ACTION_FLAG_ADD:          case ACTION_FLAG_ADD:
82          case FILTER_ACTION_FLAG_REMOVE:          case ACTION_FLAG_REMOVE:
83                  info("%d message%s flagged.\n", cnt, plural(cnt));                  info("%d message%s flagged.\n", cnt, plural(cnt));
84                  action_flag(mesgs, type, msgflags, args);                  action_flag(mesgs, type, msgflags, args);
85                  break;                  break;
86          case FILTER_ACTION_LIST:          case ACTION_LIST:
87                  info("%d message%s listed.\n", cnt, plural(cnt));                  info("%d message%s listed.\n", cnt, plural(cnt));
88                  action_list(mesgs, args);                  action_list(mesgs, args);
89                  break;                  break;
# Line 108  action_delete(char *mesgs, char *args) Line 110  action_delete(char *mesgs, char *args)
110    
111          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
112          while (tok) {          while (tok) {
113                  server_response(&connpri, imap_store(&connpri, tok,                  response_generic(&connpri, imap_store(&connpri, tok,
114                          STORE_FLAG_ADD, "\\Deleted"));                      ACTION_FLAG_ADD, "\\Deleted"));
115    
116                  tok = strtok_r(NULL, " ", &m);                  tok = strtok_r(NULL, " ", &m);
117          }          }
118    
119          if (options & OPTION_EXPUNGE)          if (opts.expunge)
120                  server_response(&connpri, imap_expunge(&connpri));                  response_generic(&connpri, imap_expunge(&connpri));
121    
122          xfree(mcp);          xfree(mcp);
123    
# Line 131  action_copy(char *mbox, char *mesgs, cha Line 133  action_copy(char *mbox, char *mesgs, cha
133  {  {
134          int r;          int r;
135          char *tok, *mcp, *m;          char *tok, *mcp, *m;
136          char dm[2][MBOX_NAME_LEN];          char dm[2][MBOX_LEN];
137    
138          r = 0;          r = 0;
139          tok = NULL;          tok = NULL;
140            *dm[0] = *dm[1] = '\0';
141    
142          action_list(mesgs, args);          action_list(mesgs, args);
143    
144          if (strchr(destmbox, '@'))          if (strchr(destmbox, '@') || strchr(destmbox, '&'))
145                  m = mcp = xstrdup(mesgs);                  m = mcp = xstrdup(mesgs);
146          else          else
147                  m = mcp = convert_messages(mesgs);                  m = mcp = convert_messages(mesgs);
148    
149          xstrncpy(dm[0], destmbox, MBOX_NAME_LEN - 1);          xstrncpy(dm[0], destmbox, MBOX_LEN - 1);
150          default_variables(mbox, dm[0]);          default_variables(mbox, dm[0]);
151          current_date(dm[0]);          system_date(dm[0]);
152          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
153          while (tok != NULL) {          while (tok != NULL) {
154                  xstrncpy(dm[1], dm[0], MBOX_NAME_LEN - 1);                  xstrncpy(dm[1], dm[0], MBOX_LEN - 1);
155                  message_date(tok, dm[1]);                  message_date(tok, dm[1]);
156                    headers_variables(tok, dm[1]);
157    
158                  if ((r = copy_response(&connpri, imap_copy(&connpri, tok,                  if ((r = response_copy(&connpri, imap_copy(&connpri, tok,
159                                  dm[1]))) == RESPONSE_TRYCREATE)                      dm[1]))) == RESPONSE_TRYCREATE)
160                          if (!server_response(&connpri, imap_create(&connpri,                          if (!response_generic(&connpri, imap_create(&connpri,
161                                      dm[1]))) {                              dm[1]))) {
162                                  if ((options & OPTION_SUBSCRIBE))                                  if (opts.subscribe)
163                                          server_response(&connpri,                                          response_generic(&connpri,
164                                              imap_subscribe(&connpri, dm[1]));                                              imap_subscribe(&connpri, dm[1]));
165                                  r = copy_response(&connpri,                                  r = response_copy(&connpri,
166                                      imap_copy(&connpri, tok, dm[1]));                                      imap_copy(&connpri, tok, dm[1]));
167                          }                          }
168                  tok = strtok_r(NULL, " ", &m);                  tok = strtok_r(NULL, " ", &m);
# Line 176  action_copy(char *mbox, char *mesgs, cha Line 180  action_copy(char *mbox, char *mesgs, cha
180  int  int
181  action_move(char *mbox, char *mesgs, char *destmbox, char *args)  action_move(char *mbox, char *mesgs, char *destmbox, char *args)
182  {  {
183    
184          if (!action_copy(mbox, mesgs, destmbox, args))          if (!action_copy(mbox, mesgs, destmbox, args))
185                  action_delete(mesgs, "\0");                  action_delete(mesgs, "\0");
186    
# Line 187  action_move(char *mbox, char *mesgs, cha Line 192  action_move(char *mbox, char *mesgs, cha
192   * Copy messages to the specified mailbox of another mail server.   * Copy messages to the specified mailbox of another mail server.
193   */   */
194  int  int
195  action_rcopy(char *mbox, char *mesgs, account_t * destacc, char *destmbox,  action_rcopy(char *mbox, char *mesgs, account_t * destacct, char *destmbox,
196      char *args)      char *args)
197  {  {
198          int r, ta, tf;          int r, ta, tf;
# Line 195  action_rcopy(char *mbox, char *mesgs, ac Line 200  action_rcopy(char *mbox, char *mesgs, ac
200          char *flags, *date;          char *flags, *date;
201          unsigned int size;          unsigned int size;
202          char buf[RESPONSE_BUF * 2 + 1];          char buf[RESPONSE_BUF * 2 + 1];
203          char dm[3][MBOX_NAME_LEN];          char dm[3][MBOX_LEN];
204    
205          *dm[0] = *dm[1] = *dm[2] = '\0';          *dm[0] = *dm[1] = *dm[2] = '\0';
206          flags = date = NULL;          flags = date = NULL;
207    
208          if (init_connection(&connaux, destacc->server, destacc->port,          if (init_connection(&connaux, destacct->server, destacct->port,
209                  destacc->ssl))              destacct->ssl))
210                  return ERROR_NETWORK;                  return ERROR_NETWORK;
211    
212          r = greeting_response(&connaux);          r = response_greeting(&connaux);
213    
214  #ifdef DEBUG          if (opts.debug)
215          test(&connaux);                  test(&connaux);
 #endif  
216    
217          if (r == RESPONSE_BYE || check_capabilities(&connaux))          if (r == RESPONSE_BYE || check_capabilities(&connaux))
218                  return ERROR_NETWORK;                  return ERROR_NETWORK;
219    
220  #ifdef SSL_TLS  #ifdef SSL_TLS
221          if (destacc->ssl == SSL_DISABLED && connaux.caps & CAPABILITY_STARTTLS)          if (destacct->ssl == SSL_DISABLED && connaux.caps & CAPABILITY_STARTTLS)
222                  if (negotiate_tls(&connaux) == RESPONSE_OK)                  if (negotiate_tls(&connaux) == RESPONSE_OK)
223                          check_capabilities(&connaux);                          check_capabilities(&connaux);
224  #endif  #endif
225    
226          if (r != RESPONSE_PREAUTH) {          if (r != RESPONSE_PREAUTH) {
227                  if (destacc->passwdattr == PASSWORD_NONE) {                  if (destacct->pass_attr == PASS_ATTR_NONE) {
228                          printf("Enter password for %s@%s: ", destacc->username,                          printf("Enter password for %s@%s: ", destacct->user,
229                              destacc->server);                              destacct->server);
230                          get_password(destacc->password, PASSWORD_LEN);                          get_password(destacct->pass, PASS_LEN);
231                          destacc->passwdattr = PASSWORD_PLAIN;                          destacct->pass_attr = PASS_ATTR_PLAIN;
232                  }                  }
233  #ifdef CRAM_MD5  #ifdef CRAM_MD5
234                  if (connaux.caps & CAPABILITY_AUTH_CRAM_MD5)                  if (connaux.caps & CAPABILITY_CRAMMD5)
235                          r = auth_cram_md5(&connaux, destacc->username,                          r = auth_cram_md5(&connaux, destacct->user,
236                              destacc->password);                              destacct->pass);
237                  else                  else
238  #endif  #endif
239                          r = login(&connaux, destacc->username,                          r = login(&connaux, destacct->user, destacct->pass);
                             destacc->password);  
240    
241                  if (r == RESPONSE_NO) {                  if (r == RESPONSE_NO) {
242                          error("username %s or password rejected at %s\n",                          error("username %s or password rejected at %s\n",
243                              destacc->username, destacc->server);                              destacct->user, destacct->server);
244                          return ERROR_NETWORK;                          return ERROR_NETWORK;
245                  }                  }
246          }          }
# Line 245  action_rcopy(char *mbox, char *mesgs, ac Line 248  action_rcopy(char *mbox, char *mesgs, ac
248    
249          m = mcp = xstrdup(mesgs);          m = mcp = xstrdup(mesgs);
250    
251          xstrncpy(dm[1], destmbox, MBOX_NAME_LEN - 1);          xstrncpy(dm[1], destmbox, MBOX_LEN - 1);
252          default_variables(mbox, dm[1]);          default_variables(mbox, dm[1]);
253          current_date(dm[1]);          system_date(dm[1]);
254    
255          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
256          while (tok != NULL) {          while (tok != NULL) {
257                  xstrncpy(dm[2], dm[1], MBOX_NAME_LEN - 1);                  xstrncpy(dm[2], dm[1], MBOX_LEN - 1);
258                  message_date(tok, dm[2]);                  message_date(tok, dm[2]);
259                    headers_variables(tok, dm[2]);
260    
261                  /* apply_namespace() returns a pointer to a static buffer. */                  /* apply_namespace() returns a pointer to a static buffer. */
262                  ndm = apply_namespace(dm[2], connaux.nsp.prefix,                  ndm = apply_namespace(dm[2], connaux.ns.prefix,
263                      connaux.nsp.delim);                      connaux.ns.delim);
264    
265                  /* Check only if mailbox name is different from last one. */                  /* Check only if mailbox name is different from last one. */
266                  if (strncmp(dm[0], dm[2], strlen(dm[2]))) {                  if (strncmp(dm[0], dm[2], strlen(dm[2]))) {
267                          r = check_mailbox(&connaux, ndm);                          r = check_mailbox(&connaux, ndm);
268                          if (r == RESPONSE_NO) {                          if (r == RESPONSE_NO) {
269                                  server_response(&connaux,                                  response_generic(&connaux,
270                                      imap_create(&connaux, ndm));                                      imap_create(&connaux, ndm));
271                                  if ((options & OPTION_SUBSCRIBE))                                  if (opts.subscribe)
272                                          server_response(&connaux,                                          response_generic(&connaux,
273                                              imap_subscribe(&connaux, ndm));                                              imap_subscribe(&connaux, ndm));
274                          }                          }
275                  }                  }
276                  xstrncpy(dm[0], dm[2], MBOX_NAME_LEN - 1);                  xstrncpy(dm[0], dm[2], MBOX_LEN - 1);
277    
278                  fetchfast_response(&connpri, &flags, &date, &size,                  response_fetchfast(&connpri, &flags, &date, &size,
279                      imap_fetch(&connpri, tok, "FAST"));                      imap_fetch(&connpri, tok, "FAST"));
280    
281                  ta = imap_append(&connaux, ndm, flags, date, size);                  ta = imap_append(&connaux, ndm, flags, date, size);
# Line 279  action_rcopy(char *mbox, char *mesgs, ac Line 283  action_rcopy(char *mbox, char *mesgs, ac
283                  xfree(flags);                  xfree(flags);
284                  xfree(date);                  xfree(date);
285    
286                  fetch_response(&connpri, 0, 1, NULL);                  response_fetch(&connpri, 0, 1, NULL);
287                  tf = imap_fetch(&connpri, tok, options & OPTION_PEEK ?                  tf = imap_fetch(&connpri, tok, opts.peek ?
288                      "BODY.PEEK[HEADER]" : "BODY[HEADER]");                      "BODY.PEEK[HEADER]" : "BODY[HEADER]");
289                  do {                  do {
290                          r = fetch_response(&connpri, tf, 0, buf);                          r = response_fetch(&connpri, tf, 0, buf);
291                          socket_write(&connaux, buf);                          socket_write(&connaux, buf);
292                  } while (r == RESPONSE_NONE);                  } while (r == RESPONSE_NONE);
293    
294                  socket_write(&connaux, "\r\n");                  socket_write(&connaux, "\r\n");
295    
296                  fetch_response(&connpri, 0, 1, NULL);                  response_fetch(&connpri, 0, 1, NULL);
297                  tf = imap_fetch(&connpri, tok, options & OPTION_PEEK ?                  tf = imap_fetch(&connpri, tok, opts.peek ?
298                      "BODY.PEEK[TEXT]" : "BODY[TEXT]");                      "BODY.PEEK[TEXT]" : "BODY[TEXT]");
299                  do {                  do {
300                          r = fetch_response(&connpri, tf, 0, buf);                          r = response_fetch(&connpri, tf, 0, buf);
301                          if (r != RESPONSE_NULLBODY)                          if (r != RESPONSE_NULLBODY)
302                                  socket_write(&connaux, buf);                                  socket_write(&connaux, buf);
303                  } while (r == RESPONSE_NONE);                  } while (r == RESPONSE_NONE);
# Line 303  action_rcopy(char *mbox, char *mesgs, ac Line 307  action_rcopy(char *mbox, char *mesgs, ac
307                  else                  else
308                          socket_write(&connaux, "\r\n");                          socket_write(&connaux, "\r\n");
309    
310                  append_response(&connaux, ta);                  response_append(&connaux, ta);
311    
312                  tok = strtok_r(NULL, " ", &m);                  tok = strtok_r(NULL, " ", &m);
313          }          }
# Line 322  action_rcopy(char *mbox, char *mesgs, ac Line 326  action_rcopy(char *mbox, char *mesgs, ac
326   * Move messages to the specified mailbox of another mail server.   * Move messages to the specified mailbox of another mail server.
327   */   */
328  int  int
329  action_rmove(char *mbox, char *mesgs, account_t * destacc, char *destmbox,  action_rmove(char *mbox, char *mesgs, account_t * destacct, char *destmbox,
330      char *args)      char *args)
331  {  {
332          if (!action_rcopy(mbox, mesgs, destacc, destmbox, args))  
333            if (!action_rcopy(mbox, mesgs, destacct, destmbox, args))
334                  action_delete(mesgs, "\0");                  action_delete(mesgs, "\0");
335    
336          return 0;          return 0;
# Line 339  int Line 344  int
344  action_flag(char *mesgs, unsigned int *type, unsigned int *msgflags,  action_flag(char *mesgs, unsigned int *type, unsigned int *msgflags,
345      char *args)      char *args)
346  {  {
         unsigned int t;  
347          char s[STORE_FLAGS_BUF];          char s[STORE_FLAGS_BUF];
348          char *tok, *m, *mcp;          char *tok, *m, *mcp;
349    
350          *s = 0;          *s = 0;
351    
352          switch (*type) {          if ((*msgflags != MSG_FLAG_NONE)) {
353          case FILTER_ACTION_FLAG_ADD:                  if ((*msgflags & MSG_FLAG_SEEN))
                 t = STORE_FLAG_ADD;  
                 break;  
         case FILTER_ACTION_FLAG_REMOVE:  
                 t = STORE_FLAG_REMOVE;  
                 break;  
         default:  
                 t = STORE_FLAG_REPLACE;  
         }  
   
         if ((*msgflags != MESSAGE_FLAG_NONE)) {  
                 if ((*msgflags & MESSAGE_FLAG_SEEN))  
354                          strncat(s, "\\Seen ", STORE_FLAGS_BUF - strlen(s) - 1);                          strncat(s, "\\Seen ", STORE_FLAGS_BUF - strlen(s) - 1);
355                  if ((*msgflags & MESSAGE_FLAG_ANSWERED))                  if ((*msgflags & MSG_FLAG_ANSWERED))
356                          strncat(s, "\\Answered ",                          strncat(s, "\\Answered ",
357                              STORE_FLAGS_BUF - strlen(s) - 1);                              STORE_FLAGS_BUF - strlen(s) - 1);
358                  if ((*msgflags & MESSAGE_FLAG_FLAGGED))                  if ((*msgflags & MSG_FLAG_FLAGGED))
359                          strncat(s, "\\Flagged ",                          strncat(s, "\\Flagged ",
360                              STORE_FLAGS_BUF - strlen(s) - 1);                              STORE_FLAGS_BUF - strlen(s) - 1);
361                  if ((*msgflags & MESSAGE_FLAG_DELETED))                  if ((*msgflags & MSG_FLAG_DELETED))
362                          strncat(s, "\\Deleted ",                          strncat(s, "\\Deleted ",
363                              STORE_FLAGS_BUF - strlen(s) - 1);                              STORE_FLAGS_BUF - strlen(s) - 1);
364                  if ((*msgflags & MESSAGE_FLAG_DRAFT))                  if ((*msgflags & MSG_FLAG_DRAFT))
365                          strncat(s, "\\Draft", STORE_FLAGS_BUF - strlen(s) - 1);                          strncat(s, "\\Draft", STORE_FLAGS_BUF - strlen(s) - 1);
366                  if ((s[strlen(s) - 1] == ' '))                  if ((s[strlen(s) - 1] == ' '))
367                          s[strlen(s) - 1] = 0;                          s[strlen(s) - 1] = 0;
# Line 379  action_flag(char *mesgs, unsigned int *t Line 372  action_flag(char *mesgs, unsigned int *t
372    
373          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
374          while (tok != NULL) {          while (tok != NULL) {
375                  server_response(&connpri, imap_store(&connpri, tok, t, s));                  response_generic(&connpri, imap_store(&connpri, tok, *type, s));
   
376                  tok = strtok_r(NULL, " ", &m);                  tok = strtok_r(NULL, " ", &m);
377          }          }
378    
379          if (options & OPTION_EXPUNGE)          if (opts.expunge)
380                  server_response(&connpri, imap_expunge(&connpri));                  response_generic(&connpri, imap_expunge(&connpri));
381    
382          xfree(mcp);          xfree(mcp);
383    
# Line 408  action_list(char *mesgs, char *args) Line 400  action_list(char *mesgs, char *args)
400    
401          m = mcp = xstrdup(mesgs);          m = mcp = xstrdup(mesgs);
402    
403          snprintf(s, ARGS_LEN + 27 - 1, options & OPTION_PEEK ?          snprintf(s, ARGS_LEN + 27 - 1, opts.peek ?
404              "BODY.PEEK[HEADER.FIELDS (%s)]" :              "BODY.PEEK[HEADER.FIELDS (%s)]" :
405              "BODY[HEADER.FIELDS (%s)]", args);              "BODY[HEADER.FIELDS (%s)]", args);
406    
407          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
408          while (tok != NULL) {          while (tok != NULL) {
409                  /* Reset internal fetch counter. */                  /* Reset internal fetch counter. */
410                  fetch_response(&connpri, 0, 1, NULL);                  response_fetch(&connpri, 0, 1, NULL);
411                  t = imap_fetch(&connpri, tok, s);                  t = imap_fetch(&connpri, tok, s);
412    
413                  log_info(LOG_PREAMBLE, NULL);                  log_info(LOG_PREAMBLE, NULL);
414                  do {                  do {
415                          r = fetch_response(&connpri, t, 0, hdrs);                          r = response_fetch(&connpri, t, 0, hdrs);
416    
417                          if (*hdrs != '\0') {                          if (*hdrs != '\0') {
418                                  if (options & OPTION_HEADERS)                                  if (opts.headers)
419                                          info("%s\n", hdrs);                                          info("%s\n", hdrs);
420                                  log_info(LOG_HEADER, hdrs);                                  log_info(LOG_HEADER, hdrs);
421                          }                          }
# Line 460  count_messages(char *mesgs) Line 452  count_messages(char *mesgs)
452    
453    
454  /*  /*
455   * Convert messages with contiguous sequence number to the corresponding   * Convert messages with contiguous sequence number to the corresponding number
456   * number range, eg. 1 2 3 5 7 8 --> 1:3 5 7:8 and return a newly allocated   * range, eg. 1 2 3 5 7 8 --> 1:3 5 7:8 and return a newly allocated buffer
457   * buffer with the results.   * with the results.
458   */   */
459  char *  char *
460  convert_messages(char *mesgs)  convert_messages(char *mesgs)
# Line 514  convert_messages(char *mesgs) Line 506  convert_messages(char *mesgs)
506    
507    
508  /*  /*
509   * Substitute all occurences of the '@' character with the '%' character,   * Substitute all occurences of the '@' character with the '%' character, and
510   * and any double '@' characters with a signle '@' character, returning the   * any double '@' characters with a signle '@' character, returning the number
511   * number of replacements.   * of replacements.
512   */   */
513  int  int
514  substitute_date(char *str)  substitute_date(char *str)
# Line 556  substitute_date(char *str) Line 548  substitute_date(char *str)
548   * specifiers.   * specifiers.
549   */   */
550  void  void
551  current_date(char *destmbox)  system_date(char *destmbox)
552  {  {
553          char s[MBOX_NAME_LEN];          char s[MBOX_LEN];
554          time_t te;          time_t te;
555          struct tm *tl;          struct tm *tl;
556    
# Line 568  current_date(char *destmbox) Line 560  current_date(char *destmbox)
560          te = time(NULL);          te = time(NULL);
561          tl = localtime(&te);          tl = localtime(&te);
562    
563          if (strftime(s, MBOX_NAME_LEN - 1, destmbox, tl))          if (strftime(s, MBOX_LEN - 1, destmbox, tl))
564                  xstrncpy(destmbox, s, MBOX_NAME_LEN - 1);                  xstrncpy(destmbox, s, MBOX_LEN - 1);
565  }  }
566    
567    
# Line 581  void Line 573  void
573  message_date(char *mesg, char *destmbox)  message_date(char *mesg, char *destmbox)
574  {  {
575          unsigned int t;          unsigned int t;
576          char s[MBOX_NAME_LEN];          char s[MBOX_LEN];
577          struct tm tl;          struct tm tl;
578          char dbuf[RESPONSE_BUF + 1];          char buf[RESPONSE_BUF + 1];
579    
580          if (!strchr(destmbox, '@'))          if (!strchr(destmbox, '@'))
581                  return;                  return;
582    
583          substitute_date(destmbox);          substitute_date(destmbox);
584    
585          fetch_response(&connpri, 0, 1, NULL);          response_fetch(&connpri, 0, 1, NULL);
586          t = imap_fetch(&connpri, mesg, options & OPTION_PEEK ?          t = imap_fetch(&connpri, mesg, opts.peek ?
587              "BODY.PEEK[HEADER.FIELDS (DATE)]" :              "BODY.PEEK[HEADER.FIELDS (DATE)]" :
588              "BODY[HEADER.FIELDS (DATE)]");              "BODY[HEADER.FIELDS (DATE)]");
589    
590          while (fetch_response(&connpri, t, 0, dbuf) == RESPONSE_NONE);          while (response_fetch(&connpri, t, 0, buf) == RESPONSE_NONE);
591    
592          if (((strptime(dbuf, "Date: %a, %d %b %Y %H:%M:%S", &tl) ||          if (((strptime(buf, "Date: %a, %d %b %Y %H:%M:%S", &tl) ||
593                      strptime(dbuf, "Date: %d %b %Y %H:%M:%S", &tl)) &&              strptime(buf, "Date: %d %b %Y %H:%M:%S", &tl)) &&
594                  strftime(s, MBOX_NAME_LEN - 1, destmbox, &tl)))              strftime(s, MBOX_LEN - 1, destmbox, &tl)))
595                  xstrncpy(destmbox, s, MBOX_NAME_LEN - 1);                  xstrncpy(destmbox, s, MBOX_LEN - 1);
596  }  }
597    
598    
# Line 618  default_variables(char *mbox, char *dest Line 610  default_variables(char *mbox, char *dest
610          s = xstrdup(destmbox);          s = xstrdup(destmbox);
611    
612          for (r = s, w = destmbox; *r != '\0';) {          for (r = s, w = destmbox; *r != '\0';) {
613                  if (w - destmbox >= MBOX_NAME_LEN - 1)                  if (w - destmbox >= MBOX_LEN - 1)
614                          break;                          break;
615                  if (*r == '$') {                  if (*r == '$') {
616                          switch (*(r + 1)) {                          switch (*(r + 1)) {
617                          case '_':                          case '_':
618                                  if (w + strlen(mbox) - destmbox >                                  if (w + strlen(mbox) - destmbox >
619                                      MBOX_NAME_LEN - 1) {                                      MBOX_LEN - 1) {
620                                          r += 2;                                          r += 2;
621                                          break;                                          break;
622                                  }                                  }
# Line 648  default_variables(char *mbox, char *dest Line 640  default_variables(char *mbox, char *dest
640    
641          xfree(s);          xfree(s);
642  }  }
643    
644    
645    /*
646     * Format the destination mailbox according to "headers variables" specifiers.
647     */
648    void
649    headers_variables(char *mesg, char *destmbox)
650    {
651            int i;
652            unsigned int t;
653            char *c, *r, *w, *s;
654            regex_t creg[2];
655            regmatch_t match[3];
656            char buf[RESPONSE_BUF + 1];
657            struct {
658                    char *s;
659                    char *e;
660            } user, domain;
661            const char *reg[2] = {
662                    "From:[[:blank:]]+([[:graph:]]+)@([[:graph:]]+)"
663                    "[[:blank:]]*\r\n",
664    
665                    "From:[[:print:]]+<([[:graph:]]+)@([[:graph:]]+)>"
666                    "[[:blank:]]*\r\n"
667            };
668    
669            if (!strchr(destmbox, '&'))
670                    return;
671    
672            response_fetch(&connpri, 0, 1, NULL);
673            t = imap_fetch(&connpri, mesg, opts.peek ?
674                "BODY.PEEK[HEADER.FIELDS (FROM)]" :
675                "BODY[HEADER.FIELDS (FROM)]");
676            while (response_fetch(&connpri, t, 0, buf) == RESPONSE_NONE);
677    
678            for (i = 0; i < 2; i++)
679                    regcomp(&creg[i], reg[i], REG_EXTENDED | REG_ICASE);
680    
681            if (!regexec(&creg[0], buf, 3, match, 0) ||
682                !regexec(&creg[1], buf, 3, match, 0)) {
683                    user.s = buf + match[1].rm_so;
684                    user.e = buf + match[1].rm_eo;
685                    domain.s = buf + match[2].rm_so;
686                    domain.e = buf + match[2].rm_eo;
687            } else {
688                    for (i = 0; i < 2; i++)
689                            regfree(&creg[i]);
690                    return;
691            }
692    
693            s = xstrdup(destmbox);
694    
695            for (r = s, w = destmbox; *r != '\0';) {
696                    if (w - destmbox >= MBOX_LEN - 1)
697                            break;
698                    if (*r == '&') {
699                            switch (*(r + 1)) {
700                            case 'f':
701                                    if (w + (user.e - user.s) +
702                                        (domain.s - domain.e) + 1 -
703                                        destmbox > MBOX_LEN) {
704                                            r += 2;
705                                            break;
706                                    }
707                                    for (c = user.s; c < user.e; c++, w++)
708                                            *w = *c;
709                                    *w++ = '@';
710                                    for (c = domain.s; c < domain.e; c++, w++)
711                                            *w = *c;
712                                    r += 2;
713                                    break;
714                            case 'u':
715                                    if (w + (user.e - user.s) - destmbox >
716                                        MBOX_LEN - 1) {
717                                            r += 2;
718                                            break;
719                                    }
720                                    for (c = user.s; c < user.e; c++, w++)
721                                            *w = *c;
722                                    r += 2;
723                                    break;
724                            case 'd':
725                                    if (w + (domain.e - domain.s) - destmbox >
726                                        MBOX_LEN - 1) {
727                                            r += 2;
728                                            break;
729                                    }
730                                    for (c = domain.s; c < domain.e; c++, w++)
731                                            *w = *c;
732                                    r += 2;
733                                    break;
734                            case '&':
735                                    *w++ = '&';
736                                    r += 2;
737                                    break;
738                            default:
739                                    *w++ = *r++;
740                                    break;
741                            }
742                    } else {
743                            *w++ = *r++;
744                    }
745            }
746            *w = '\0';
747    
748            for (i = 0; i < 2; i++)
749                    regfree(&creg[i]);
750            xfree(s);
751    }

Legend:
Removed from v.1.2.2.6  
changed lines
  Added in v.1.17

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26