/[mailutils]/mailutils/imap4d/util.c
ViewVC logotype

Diff of /mailutils/imap4d/util.c

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

revision 1.45 by polak, Tue Dec 24 08:25:36 2002 UTC revision 1.46 by polak, Fri Jan 17 19:07:15 2003 UTC
# Line 1  Line 1 
1  /* GNU Mailutils -- a suite of utilities for electronic mail  /* GNU Mailutils -- a suite of utilities for electronic mail
2     Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.     Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3    
4     GNU Mailutils is free software; you can redistribute it and/or modify     GNU Mailutils is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 13  Line 13 
13    
14     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
15     along with GNU Mailutils; if not, write to the Free Software     along with GNU Mailutils; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA  */
17    
18  #include "imap4d.h"  #include "imap4d.h"
19    
20    static FILE *ifile;
21    static FILE *ofile;
22    #ifdef WITH_TLS
23    static gnutls_session sfile;
24    #endif /* WITH_TLS */
25    
26  static int add2set __P ((size_t **, int *, unsigned long));  static int add2set __P ((size_t **, int *, unsigned long));
27  static const char *sc2string __P ((int));  static const char *sc2string __P ((int));
28    
# Line 36  util_getitem (char *s, const char *delim Line 42  util_getitem (char *s, const char *delim
42      char *p;      char *p;
43      if ((p = s) || (p = *save))      if ((p = s) || (p = *save))
44        {        {
45          while (isspace ((unsigned)*p))          while (isspace ((unsigned) *p))
46            p++;            p++;
47          if (*p == '"')          if (*p == '"')
48            {            {
# Line 45  util_getitem (char *s, const char *delim Line 51  util_getitem (char *s, const char *delim
51              while (*p && *p != '"')              while (*p && *p != '"')
52                p++;                p++;
53              if (*p == '"')              if (*p == '"')
54                  p++;                p++;
55              *save = (*p) ? p + 1 : p;              *save = (*p) ? p + 1 : p;
56              *p = '\0';              *p = '\0';
57              return s;              return s;
# Line 70  util_token (char *buf, size_t len, char Line 76  util_token (char *buf, size_t len, char
76    for (i = 1; **ptr && i < len; (*ptr)++, buf++, i++)    for (i = 1; **ptr && i < len; (*ptr)++, buf++, i++)
77      {      {
78        if (**ptr == ' ' || **ptr == '.'        if (**ptr == ' ' || **ptr == '.'
79            || **ptr == '(' || **ptr == ')'            || **ptr == '(' || **ptr == ')'
80            || **ptr == '[' || **ptr == ']'            || **ptr == '[' || **ptr == ']'
81            || **ptr == '<' || **ptr  == '>'            || **ptr == '<' || **ptr == '>' || **ptr == '\r' || **ptr == '\n')
82            || **ptr == '\r' || **ptr == '\n')          {
83          {            /* Advance.  */
84            /* Advance.  */            if (start == (*ptr))
85            if (start == (*ptr))              (*ptr)++;
86              (*ptr)++;            break;
87            break;          }
         }  
88        *buf = **ptr;        *buf = **ptr;
89    }      }
90    *buf = '\0';    *buf = '\0';
91    /* Skip trailing space.  */    /* Skip trailing space.  */
92    while (**ptr && **ptr == ' ')    while (**ptr && **ptr == ' ')
93      (*ptr)++;      (*ptr)++;
94    return  *ptr - start;    return *ptr - start;
95  }  }
96    
97  /* Remove the surrounding double quotes.  */  /* Remove the surrounding double quotes.  */
# Line 100  util_unquote (char **ptr) Line 105  util_unquote (char **ptr)
105      {      {
106        char *p = ++s;        char *p = ++s;
107        while (*p && *p != '"')        while (*p && *p != '"')
108          p++;          p++;
109        if (*p == '"')        if (*p == '"')
110          *p = '\0';          *p = '\0';
111      }      }
112    *ptr = s;    *ptr = s;
113  }  }
# Line 123  util_getfullpath (char *name, const char Line 128  util_getfullpath (char *name, const char
128    char *p = util_tilde_expansion (name, delim);    char *p = util_tilde_expansion (name, delim);
129    if (*p != delim[0])    if (*p != delim[0])
130      {      {
131        char *s = calloc (strlen (homedir) + strlen (delim) + strlen (p) + 1, 1);        char *s =
132            calloc (strlen (homedir) + strlen (delim) + strlen (p) + 1, 1);
133        sprintf (s, "%s%s%s", homedir, delim, p);        sprintf (s, "%s%s%s", homedir, delim, p);
134        free (p);        free (p);
135        p = s;        p = s;
# Line 134  util_getfullpath (char *name, const char Line 140  util_getfullpath (char *name, const char
140  static int  static int
141  comp_int (const void *a, const void *b)  comp_int (const void *a, const void *b)
142  {  {
143    return *(int*)a - *(int*)b;    return *(int *) a - *(int *) b;
144  }  }
145    
146  /* Return in set an allocated array contain (n) numbers, for imap messsage set  /* Return in set an allocated array contain (n) numbers, for imap messsage set
# Line 150  comp_int (const void *a, const void *b) Line 156  comp_int (const void *a, const void *b)
156     FIXME: The algo below is to relaxe, things like <,,,> or <:12> or <20:10>     FIXME: The algo below is to relaxe, things like <,,,> or <:12> or <20:10>
157     will not generate an error.  */     will not generate an error.  */
158  int  int
159  util_msgset (char *s, size_t **set, int *n, int isuid)  util_msgset (char *s, size_t ** set, int *n, int isuid)
160  {  {
161    unsigned long val = 0;    unsigned long val = 0;
162    unsigned long low = 0;    unsigned long low = 0;
# Line 158  util_msgset (char *s, size_t **set, int Line 164  util_msgset (char *s, size_t **set, int
164    int status = 0;    int status = 0;
165    size_t max = 0;    size_t max = 0;
166    size_t *tmp;    size_t *tmp;
167    int i,j;    int i, j;
168    
169    status = mailbox_messages_count (mbox, &max);    status = mailbox_messages_count (mbox, &max);
170    if (status != 0)    if (status != 0)
# Line 178  util_msgset (char *s, size_t **set, int Line 184  util_msgset (char *s, size_t **set, int
184        switch (*s)        switch (*s)
185          {          {
186            /* isdigit */            /* isdigit */
187          case '0': case '1': case '2': case '3': case '4':          case '0':
188          case '5': case '6': case '7': case '8': case '9':          case '1':
189            case '2':
190            case '3':
191            case '4':
192            case '5':
193            case '6':
194            case '7':
195            case '8':
196            case '9':
197            {            {
198              errno = 0;              errno = 0;
199              val = strtoul (s, &s, 10);              val = strtoul (s, &s, 10);
# Line 206  util_msgset (char *s, size_t **set, int Line 220  util_msgset (char *s, size_t **set, int
220                      low = val;                      low = val;
221                      val = tmp;                      val = tmp;
222                    }                    }
223                  for (;low && low <= val; low++)                  for (; low && low <= val; low++)
224                    {                    {
225                      status = add2set (set, n, low);                      status = add2set (set, n, low);
226                      if (status != 0)                      if (status != 0)
# Line 227  util_msgset (char *s, size_t **set, int Line 241  util_msgset (char *s, size_t **set, int
241               contiguous set of mesages ranging from the first number to the               contiguous set of mesages ranging from the first number to the
242               second:               second:
243               3:5  --> 3 4 5               3:5  --> 3 4 5
244            */             */
245          case ':':          case ':':
246            low = val + 1;            low = val + 1;
247            s++;            s++;
# Line 236  util_msgset (char *s, size_t **set, int Line 250  util_msgset (char *s, size_t **set, int
250            /* As a convenience. '*' is provided to refer to the highest message            /* As a convenience. '*' is provided to refer to the highest message
251               number int the mailbox:               number int the mailbox:
252               5:*  --> 5 6 7 8               5:*  --> 5 6 7 8
253            */             */
254          case '*':          case '*':
255            {            {
256              val = max;              val = max;
# Line 250  util_msgset (char *s, size_t **set, int Line 264  util_msgset (char *s, size_t **set, int
264            /* IMAP also allows a set of noncontiguous numbers to be specified            /* IMAP also allows a set of noncontiguous numbers to be specified
265               with the ',' character:               with the ',' character:
266               1,3,5,7  --> 1 3 5 7               1,3,5,7  --> 1 3 5 7
267            */             */
268          case ',':          case ',':
269            s++;            s++;
270            break;            break;
# Line 262  util_msgset (char *s, size_t **set, int Line 276  util_msgset (char *s, size_t **set, int
276            *n = 0;            *n = 0;
277            return EINVAL;            return EINVAL;
278    
279          } /* switch */          }                       /* switch */
280    
281        if (done)        if (done)
282          break;          break;
283      } /* while */      }                           /* while */
284    
285    if (low)    if (low)
286      {      {
# Line 284  util_msgset (char *s, size_t **set, int Line 298  util_msgset (char *s, size_t **set, int
298            low = val;            low = val;
299            val = tmp;            val = tmp;
300          }          }
301        for (;low && low <= val; low++)        for (; low && low <= val; low++)
302          {          {
303            status = add2set (set, n, low);            status = add2set (set, n, low);
304            if (status != 0)            if (status != 0)
# Line 298  util_msgset (char *s, size_t **set, int Line 312  util_msgset (char *s, size_t **set, int
312    /* Remove duplicates. tmp serves to avoid extra dereferences */    /* Remove duplicates. tmp serves to avoid extra dereferences */
313    tmp = *set;    tmp = *set;
314    for (i = 0, j = 1; i < *n; i++)    for (i = 0, j = 1; i < *n; i++)
315      if (tmp[j-1] != tmp[i])      if (tmp[j - 1] != tmp[i])
316        tmp[j++] = tmp[i];        tmp[j++] = tmp[i];
317    *n = j;    *n = j;
318    return 0;    return 0;
319  }  }
320    
321  /* Use vfprintf for the dirty work.  */  static int
322    util_send_lowlevel (char *buf)
323    {
324      int status;
325    
326      if (buf)
327        {
328    #ifdef WITH_TLS
329          if (tls_done)
330            status = gnutls_record_send (sfile, buf, strlen (buf));
331          else
332    #endif /* WITH_TLS */
333            status = fprintf (ofile, buf);
334        }
335    
336      return status;
337    }
338    
339  int  int
340  util_send (const char *format, ...)  util_send (const char *format, ...)
341  {  {
342    int status;    char *buf = NULL;
343      int status = 0;
344    va_list ap;    va_list ap;
345    
346    va_start (ap, format);    va_start (ap, format);
347      vasprintf (&buf, format, ap);
348    
349    if (daemon_param.transcript)    if (buf)
350      {      {
351        char *buf;        if (daemon_param.transcript)
352        vasprintf (&buf, format, ap);          syslog (LOG_DEBUG, "sent: %s", buf);
353        if (buf)  
354          {        status = util_send_lowlevel (buf);
355            syslog (LOG_DEBUG, "sent: %s", buf);        free (buf);
           free (buf);  
         }  
356      }      }
357    
   status = vfprintf (ofile, format, ap);  
358    va_end (ap);    va_end (ap);
359    return status;    return status;
360  }  }
# Line 361  util_send_literal (const char *buffer) Line 392  util_send_literal (const char *buffer)
392  int  int
393  util_out (int rc, const char *format, ...)  util_out (int rc, const char *format, ...)
394  {  {
395      char *tempbuf = NULL;
396    char *buf = NULL;    char *buf = NULL;
397    int status;    int status = 0;
398    va_list ap;    va_list ap;
399    asprintf (&buf, "* %s%s\r\n", sc2string (rc), format);  
400      asprintf (&tempbuf, "* %s%s\r\n", sc2string (rc), format);
401    va_start (ap, format);    va_start (ap, format);
402    if (daemon_param.transcript)    vasprintf (&buf, tempbuf, ap);
403    
404      if (buf)
405      {      {
406        char *buf1 = NULL;        if (daemon_param.transcript)
407        vasprintf (&buf1, buf, ap);          syslog (LOG_DEBUG, "sent: %s", buf);
408        if (buf1)  
409          {        status = util_send_lowlevel (buf);
410            syslog (LOG_DEBUG, "sent: %s", buf1);        free (buf);
           free (buf1);  
         }  
411      }      }
412    status = vfprintf (ofile, buf, ap);  
413    va_end (ap);    va_end (ap);
414    free (buf);    free (tempbuf);
415    return status;    return status;
416  }  }
417    
# Line 386  util_out (int rc, const char *format, .. Line 419  util_out (int rc, const char *format, ..
419  int  int
420  util_finish (struct imap4d_command *command, int rc, const char *format, ...)  util_finish (struct imap4d_command *command, int rc, const char *format, ...)
421  {  {
422      char *tempbuf = NULL;
423    char *buf = NULL;    char *buf = NULL;
424    int new_state;    int new_state;
425    int status;    int status = 0;
426    va_list ap;    va_list ap;
427    
428    asprintf (&buf, "%s %s%s %s\r\n", command->tag, sc2string (rc),    asprintf (&tempbuf, "%s %s%s %s\r\n", command->tag, sc2string (rc),
429              command->name, format);              command->name, format);
   
430    va_start (ap, format);    va_start (ap, format);
431    if (daemon_param.transcript)    vasprintf (&buf, tempbuf, ap);
432    
433      if (buf)
434      {      {
435        char *buf1 = NULL;        if (daemon_param.transcript)
436        vasprintf (&buf1, buf, ap);          syslog (LOG_DEBUG, "sent: %s", buf);
437        if (buf1)  
438          {        status = util_send_lowlevel (buf);
439            syslog (LOG_DEBUG, "sent: %s", buf1);        free (buf);
           free (buf1);  
         }  
440      }      }
441      
   status = vfprintf (ofile, buf, ap);  
442    va_end (ap);    va_end (ap);
443    free (buf);    free (tempbuf);
444    
445    /* Reset the state.  */    /* Reset the state.  */
446    if (rc == RESP_OK)    if (rc == RESP_OK)
447      new_state = command->success;      new_state = command->success;
# Line 416  util_finish (struct imap4d_command *comm Line 449  util_finish (struct imap4d_command *comm
449      new_state = command->failure;      new_state = command->failure;
450    else    else
451      new_state = STATE_NONE;      new_state = STATE_NONE;
452      
453    if (new_state != STATE_NONE)    if (new_state != STATE_NONE)
454      state = new_state;      state = new_state;
455    
456    return status;    return status;
457  }  }
458    
# Line 429  util_finish (struct imap4d_command *comm Line 463  util_finish (struct imap4d_command *comm
463     the number of octets, close brace ("}"), and CRLF.     the number of octets, close brace ("}"), and CRLF.
464   */   */
465  char *  char *
466  imap4d_readline (FILE *fp)  imap4d_readline (void)
467  {  {
468    char buffer[512];    char buffer[512];
469    size_t len;    size_t len;
# Line 440  imap4d_readline (FILE *fp) Line 474  imap4d_readline (FILE *fp)
474    if (!line)    if (!line)
475      imap4d_bye (ERR_NO_MEM);      imap4d_bye (ERR_NO_MEM);
476    
477    line[0] = '\0'; /* start with a empty string.  */    line[0] = '\0';               /* start with a empty string.  */
478    do    do
479      {      {
480        alarm (daemon_param.timeout);        alarm (daemon_param.timeout);
481        if (fgets (buffer, sizeof (buffer), fp) == NULL)  #ifdef WITH_TLS
482          if (tls_done)
483            {
484              len = gnutls_record_recv (sfile, buffer, sizeof (buffer) - 1);
485              if (len < 0)
486                {
487                  syslog (LOG_INFO, _("TLS error on read: %s"),
488                          gnutls_strerror (len));
489                  imap4d_bye (ERR_TLS);
490                }
491              else
492                buffer[len] = 0;
493            }
494          else
495    #endif /* WITH_TLS */
496          if (fgets (buffer, sizeof (buffer), ifile) == NULL)
497          {          {
498            if (feof (fp))            if (feof (ifile))
499              syslog (LOG_INFO, _("unexpected eof on input"));              syslog (LOG_INFO, _("unexpected eof on input"));
500            else if (errno)            else if (errno)
501              syslog (LOG_INFO, _("error reading from input file: %m"));              syslog (LOG_INFO, _("error reading from input file: %m"));
# Line 458  imap4d_readline (FILE *fp) Line 507  imap4d_readline (FILE *fp)
507    
508        len = strlen (buffer);        len = strlen (buffer);
509        /* If we were in a litteral substract. We have to do it here since the CR        /* If we were in a litteral substract. We have to do it here since the CR
510           is part of the count in a literal.  */           is part of the count in a literal.  */
511        if (number)        if (number)
512          number -= len;          number -= len;
513    
514        /* Remove CR.  */        /* Remove CR.  */
515        if (len > 1 && buffer[len - 1] == '\n')        if (len > 1 && buffer[len - 1] == '\n')
# Line 479  imap4d_readline (FILE *fp) Line 528  imap4d_readline (FILE *fp)
528        total = strlen (line);        total = strlen (line);
529    
530        /* I observe some client requesting long FETCH operations since, I did        /* I observe some client requesting long FETCH operations since, I did
531           not see any limit in the command length in the RFC, catch things           not see any limit in the command length in the RFC, catch things
532           here.  */           here.  */
533        /* Check that we do have a terminated NL line and we are not retrieving        /* Check that we do have a terminated NL line and we are not retrieving
534           a literal. If we don't continue the read.  */           a literal. If we don't continue the read.  */
535        if (number <= 0 && total && line[total - 1] != '\n')        if (number <= 0 && total && line[total - 1] != '\n')
536          continue;          continue;
537    
538        /* Check if the client try to send a literal and make sure we are not        /* Check if the client try to send a literal and make sure we are not
539           already retrieving a literal.  */           already retrieving a literal.  */
540        if (number <= 0 && len > 2)        if (number <= 0 && len > 2)
541          {          {
542            size_t n = total - 1; /* C arrays are 0-based.  */            size_t n = total - 1; /* C arrays are 0-based.  */
543            /* A literal is this "{number}\n".  The CR is already strip.  */            /* A literal is this "{number}\n".  The CR is already strip.  */
544            if (line[n] == '\n' && line[n - 1] == '}')            if (line[n] == '\n' && line[n - 1] == '}')
545              {              {
546                /* Search for the matching bracket.  */                /* Search for the matching bracket.  */
547                while (n && line[n] != '{') n--;                while (n && line[n] != '{')
548                if (line [n] == '{')                  n--;
549                  {                if (line[n] == '{')
550                    char *sp = NULL;                  {
551                      char *sp = NULL;
552                    /* Truncate where the literal number was.  */                    /* Truncate where the literal number was.  */
553                    line[n] = '\0';                    line[n] = '\0';
554                    number = strtoul (line + n + 1, &sp, 10);                    number = strtoul (line + n + 1, &sp, 10);
555                    /* Client can ask for non synchronise literal,                    /* Client can ask for non synchronise literal,
556                     if a '+' is append to the octet count. */                       if a '+' is append to the octet count. */
557                    if (*sp != '+')                    if (*sp != '+')
558                      util_send ("+ GO AHEAD\r\n");                      util_send ("+ GO AHEAD\r\n");
559                  }                  }
560              }              }
561          }          }
562      }      }
563    while (number > 0 || (total && line[total - 1] != '\n'));    while (number > 0 || (total && line[total - 1] != '\n'));
564    if (daemon_param.transcript)    if (daemon_param.transcript)
# Line 517  imap4d_readline (FILE *fp) Line 567  imap4d_readline (FILE *fp)
567  }  }
568    
569  char *  char *
570  imap4d_readline_ex (FILE *fp)  imap4d_readline_ex (void)
571  {  {
572    int len;    int len;
573    char *s = imap4d_readline (fp);    char *s = imap4d_readline ();
574    
575    if (s && (len = strlen (s)) > 0 && s[len-1] == '\n')    if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n')
576        s[len-1] = 0;      s[len - 1] = 0;
577    return s;    return s;
578  }  }
579          
580  int  int
581  util_do_command (char *prompt)  util_do_command (char *prompt)
582  {  {
# Line 540  util_do_command (char *prompt) Line 590  util_do_command (char *prompt)
590    if (!tag)    if (!tag)
591      {      {
592        nullcommand.name = "";        nullcommand.name = "";
593        nullcommand.tag = (char *)"*";        nullcommand.tag = (char *) "*";
594        return util_finish (&nullcommand, RESP_BAD, "Null command");        return util_finish (&nullcommand, RESP_BAD, "Null command");
595      }      }
596    else if (!cmd)    else if (!cmd)
# Line 557  util_do_command (char *prompt) Line 607  util_do_command (char *prompt)
607      {      {
608        nullcommand.name = "";        nullcommand.name = "";
609        nullcommand.tag = tag;        nullcommand.tag = tag;
610        return util_finish (&nullcommand, RESP_BAD,  "Invalid command");        return util_finish (&nullcommand, RESP_BAD, "Invalid command");
611      }      }
612              
613    command->tag = tag;    command->tag = tag;
614    
615    if (command->states && (command->states & state) == 0)    if (command->states && (command->states & state) == 0)
616      return util_finish (command, RESP_BAD, "Wrong state");      return util_finish (command, RESP_BAD, "Wrong state");
617      
618    len = strlen (sp);    len = strlen (sp);
619    if (len  && sp[len - 1] == '\n')    if (len && sp[len - 1] == '\n')
620      sp[len - 1] = '\0';      sp[len - 1] = '\0';
621    return command->func (command, sp);    return command->func (command, sp);
622  }  }
# Line 577  util_upper (char *s) Line 627  util_upper (char *s)
627    if (!s)    if (!s)
628      return 0;      return 0;
629    for (; *s; s++)    for (; *s; s++)
630      *s = toupper ((unsigned)*s);      *s = toupper ((unsigned) *s);
631    return 0;    return 0;
632  }  }
633    
# Line 585  util_upper (char *s) Line 635  util_upper (char *s)
635  int  int
636  util_start (char *tag)  util_start (char *tag)
637  {  {
638    (void)tag;    (void) tag;
639    return 0;    return 0;
640  }  }
641    
# Line 632  sc2string (int rc) Line 682  sc2string (int rc)
682  }  }
683    
684  static int  static int
685  add2set (size_t **set, int *n, unsigned long val)  add2set (size_t ** set, int *n, unsigned long val)
686  {  {
687    size_t *tmp;    size_t *tmp;
688    tmp = realloc (*set, (*n + 1) * sizeof (**set));    tmp = realloc (*set, (*n + 1) * sizeof (**set));
# Line 650  add2set (size_t **set, int *n, unsigned Line 700  add2set (size_t **set, int *n, unsigned
700  }  }
701    
702  int  int
703  util_parse_internal_date0 (char *date, time_t *timep, char **endp)  util_parse_internal_date0 (char *date, time_t * timep, char **endp)
704  {  {
705    struct tm tm;    struct tm tm;
706    mu_timezone tz;    mu_timezone tz;
707    time_t time;    time_t time;
708    char **datep = &date;    char **datep = &date;
709    
710    if (mu_parse_imap_date_time((const char **)datep, &tm, &tz))    if (mu_parse_imap_date_time ((const char **) datep, &tm, &tz))
711      return 1;      return 1;
712    
713    time = mu_tm2time (&tm, &tz);    time = mu_tm2time (&tm, &tz);
714    if (time == (time_t) -1)    if (time == (time_t) - 1)
715      return 2;      return 2;
716    
717    *timep = time;    *timep = time;
# Line 671  util_parse_internal_date0 (char *date, t Line 721  util_parse_internal_date0 (char *date, t
721  }  }
722    
723  int  int
724  util_parse_internal_date (char *date, time_t *timep)  util_parse_internal_date (char *date, time_t * timep)
725  {  {
726    return util_parse_internal_date0 (date, timep, NULL);    return util_parse_internal_date0 (date, timep, NULL);
727  }  }
728    
729    
730  int  int
731  util_parse_822_date (char *date, time_t *timep)  util_parse_822_date (char *date, time_t * timep)
732  {  {
733    struct tm tm;    struct tm tm;
734    mu_timezone tz;    mu_timezone tz;
735    const char* p = date;    const char *p = date;
736    
737    if (parse822_date_time(&p, date+strlen(date), &tm, &tz) == 0)    if (parse822_date_time (&p, date + strlen (date), &tm, &tz) == 0)
738      {      {
739        *timep = mu_tm2time (&tm, &tz);        *timep = mu_tm2time (&tm, &tz);
740        return 0;        return 0;
# Line 693  util_parse_822_date (char *date, time_t Line 743  util_parse_822_date (char *date, time_t
743  }  }
744    
745  int  int
746  util_parse_ctime_date (const char *date, time_t *timep)  util_parse_ctime_date (const char *date, time_t * timep)
747  {  {
748    struct tm tm;    struct tm tm;
749    mu_timezone tz;    mu_timezone tz;
750    
751    if (mu_parse_ctime_date_time(&date, &tm, &tz) == 0)    if (mu_parse_ctime_date_time (&date, &tm, &tz) == 0)
752      {      {
753        *timep = mu_tm2time (&tm, &tz);        *timep = mu_tm2time (&tm, &tz);
754        return 0;        return 0;
# Line 711  util_parse_ctime_date (const char *date, Line 761  util_parse_ctime_date (const char *date,
761  char *  char *
762  util_strcasestr (const char *haystack, const char *needle)  util_strcasestr (const char *haystack, const char *needle)
763  {  {
764    register char *needle_end = strchr(needle, '\0');    register char *needle_end = strchr (needle, '\0');
765    register char *haystack_end = strchr(haystack, '\0');    register char *haystack_end = strchr (haystack, '\0');
766    register size_t needle_len = needle_end - needle;    register size_t needle_len = needle_end - needle;
767    register size_t needle_last = needle_len - 1;    register size_t needle_last = needle_len - 1;
768    register const char *begin;    register const char *begin;
# Line 729  util_strcasestr (const char *haystack, c Line 779  util_strcasestr (const char *haystack, c
779        register const char *h = begin;        register const char *h = begin;
780    
781        do        do
782          if (tolower(*h) != tolower(*n))          if (tolower (*h) != tolower (*n))
783            goto loop;            /* continue for loop */            goto loop;            /* continue for loop */
784        while (--n >= needle && --h >= haystack);        while (--n >= needle && --h >= haystack);
785    
# Line 746  struct Line 796  struct
796  {  {
797    char *name;    char *name;
798    int flag;    int flag;
799  } _imap4d_attrlist[] = {  }
800    { "\\Answered", MU_ATTRIBUTE_ANSWERED },  _imap4d_attrlist[] =
801    { "\\Flagged",  MU_ATTRIBUTE_FLAGGED },  {
802    { "\\Deleted", MU_ATTRIBUTE_DELETED },    {
803    { "\\Draft", MU_ATTRIBUTE_DRAFT },    "\\Answered", MU_ATTRIBUTE_ANSWERED}
804    { "\\Seen", MU_ATTRIBUTE_READ },    ,
805    { "\\Recent", MU_ATTRIBUTE_RECENT },    {
806  };    "\\Flagged", MU_ATTRIBUTE_FLAGGED}
807      ,
808      {
809      "\\Deleted", MU_ATTRIBUTE_DELETED}
810      ,
811      {
812      "\\Draft", MU_ATTRIBUTE_DRAFT}
813      ,
814      {
815      "\\Seen", MU_ATTRIBUTE_READ}
816      ,
817      {
818      "\\Recent", MU_ATTRIBUTE_RECENT}
819    ,};
820    
821  #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0])  #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0])
822    
# Line 781  util_type_to_attribute (int type, char * Line 844  util_type_to_attribute (int type, char *
844    int i;    int i;
845    size_t len = 0;    size_t len = 0;
846    
847    if (MU_ATTRIBUTE_IS_UNSEEN(type))    if (MU_ATTRIBUTE_IS_UNSEEN (type))
848      *attr_str = strdup("\\Recent");      *attr_str = strdup ("\\Recent");
849    else    else
850      *attr_str = NULL;      *attr_str = NULL;
851    
# Line 790  util_type_to_attribute (int type, char * Line 853  util_type_to_attribute (int type, char *
853      if (type & _imap4d_attrlist[i].flag)      if (type & _imap4d_attrlist[i].flag)
854        {        {
855          attr_list[nattr++] = _imap4d_attrlist[i].name;          attr_list[nattr++] = _imap4d_attrlist[i].name;
856          len += 1 + strlen(_imap4d_attrlist[i].name);          len += 1 + strlen (_imap4d_attrlist[i].name);
857        }        }
858      
859    *attr_str = malloc(len+1);    *attr_str = malloc (len + 1);
860    (*attr_str)[0] = 0;    (*attr_str)[0] = 0;
861    if (*attr_str)    if (*attr_str)
862      {      {
863        for (i = 0; i < nattr; i++)        for (i = 0; i < nattr; i++)
864          {          {
865            strcat(*attr_str, attr_list[i]);            strcat (*attr_str, attr_list[i]);
866            if (i != nattr-1)            if (i != nattr - 1)
867              strcat(*attr_str, " ");              strcat (*attr_str, " ");
868          }          }
869      }      }
870      
871    if (!*attr_str)    if (!*attr_str)
872      imap4d_bye (ERR_NO_MEM);      imap4d_bye (ERR_NO_MEM);
873    return 0;    return 0;
874  }  }
875    
876  void  void
877  util_print_flags(attribute_t attr)  util_print_flags (attribute_t attr)
878  {  {
879    int i;    int i;
880    int flags = 0;    int flags = 0;
881    int space = 0;    int space = 0;
882      
883    attribute_get_flags (attr, &flags);    attribute_get_flags (attr, &flags);
884    for (i = 0; i < _imap4d_nattr; i++)    for (i = 0; i < _imap4d_nattr; i++)
885      if (flags & _imap4d_attrlist[i].flag)      if (flags & _imap4d_attrlist[i].flag)
# Line 827  util_print_flags(attribute_t attr) Line 890  util_print_flags(attribute_t attr)
890            space = 1;            space = 1;
891          util_send (_imap4d_attrlist[i].name);          util_send (_imap4d_attrlist[i].name);
892        }        }
893      
894    if (MU_ATTRIBUTE_IS_UNSEEN(flags))    if (MU_ATTRIBUTE_IS_UNSEEN (flags))
895      {      {
896        if (space)        if (space)
897            util_send (" ");          util_send (" ");
898        util_send ("\\Recent");        util_send ("\\Recent");
899      }      }
900  }  }
# Line 840  int Line 903  int
903  util_attribute_matches_flag (attribute_t attr, const char *item)  util_attribute_matches_flag (attribute_t attr, const char *item)
904  {  {
905    int flags = 0, mask = 0;    int flags = 0, mask = 0;
906      
907    attribute_get_flags (attr, &flags);    attribute_get_flags (attr, &flags);
908    util_attribute_to_type (item, &mask);    util_attribute_to_type (item, &mask);
909    if (mask == MU_ATTRIBUTE_RECENT)    if (mask == MU_ATTRIBUTE_RECENT)
# Line 851  util_attribute_matches_flag (attribute_t Line 914  util_attribute_matches_flag (attribute_t
914    
915    
916  int  int
917  util_parse_attributes(char *items, char **save, int *flags)  util_parse_attributes (char *items, char **save, int *flags)
918  {  {
919    int rc = 0;    int rc = 0;
920    
# Line 880  util_parse_attributes(char *items, char Line 943  util_parse_attributes(char *items, char
943    
944  int  int
945  util_base64_encode (const unsigned char *input, size_t input_len,  util_base64_encode (const unsigned char *input, size_t input_len,
946                      unsigned char **output, size_t *output_len)                      unsigned char **output, size_t * output_len)
947  {  {
948    static char b64tab[] =    static char b64tab[] =
949      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
950    size_t olen = 4 * (input_len + 2) / 3;    size_t olen = 4 * (input_len + 2) / 3;
951    unsigned char *out = malloc (olen);    unsigned char *out = malloc (olen);
952      
953    if (!out)    if (!out)
954      return 1;      return 1;
955    *output = out;    *output = out;
# Line 896  util_base64_encode (const unsigned char Line 959  util_base64_encode (const unsigned char
959        *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)];        *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)];
960        *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)];        *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)];
961        *out++ = b64tab[input[2] & 0x3f];        *out++ = b64tab[input[2] & 0x3f];
962        olen  -= 4;        olen -= 4;
963        input_len -= 3;        input_len -= 3;
964        input += 3;        input += 3;
965      }      }
# Line 917  util_base64_encode (const unsigned char Line 980  util_base64_encode (const unsigned char
980    
981  int  int
982  util_base64_decode (const unsigned char *input, size_t input_len,  util_base64_decode (const unsigned char *input, size_t input_len,
983                      unsigned char **output, size_t *output_len)                      unsigned char **output, size_t * output_len)
984  {  {
985    static int b64val[128] = {    static int b64val[128] = {
986      -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
987      -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
988      -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, 62, -1, -1, -1, 63,      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
989      52, 53, 54, 55, 56, 57, 58, 59,  60, 61, -1, -1, -1, -1, -1, -1,      52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
990      -1,  0,  1,  2,  3,  4,  5,  6,   7,  8,  9, 10, 11, 12, 13, 14,      -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
991      15, 16, 17, 18, 19, 20, 21, 22,  23, 24, 25, -1, -1, -1, -1, -1,      15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
992      -1, 26, 27, 28, 29, 30, 31, 32,  33, 34, 35, 36, 37, 38, 39, 40,      -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
993      41, 42, 43, 44, 45, 46, 47, 48,  49, 50, 51, -1, -1, -1, -1, -1      41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
994    };    };
995    int olen = input_len;    int olen = input_len;
996    unsigned char *out = malloc (olen);    unsigned char *out = malloc (olen);
# Line 940  util_base64_decode (const unsigned char Line 1003  util_base64_decode (const unsigned char
1003        if (input[0] > 127 || b64val[input[0]] == -1        if (input[0] > 127 || b64val[input[0]] == -1
1004            || input[1] > 127 || b64val[input[1]] == -1            || input[1] > 127 || b64val[input[1]] == -1
1005            || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1))            || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1))
1006            || input[3] > 127 || ((input[3] != '=') && (b64val[input[3]] == -1)))            || input[3] > 127 || ((input[3] != '=')
1007                                    && (b64val[input[3]] == -1)))
1008          return -1;          return -1;
1009        *out++ = (b64val[input[0]] << 2) | (b64val[input[1]] >> 4);        *out++ = (b64val[input[0]] << 2) | (b64val[input[1]] >> 4);
1010        if (input[2] != '=')        if (input[2] != '=')
# Line 968  util_localname () Line 1032  util_localname ()
1032        int name_len = 256;        int name_len = 256;
1033        int status = 1;        int status = 1;
1034        struct hostent *hp;        struct hostent *hp;
1035          
1036        name = malloc (name_len);        name = malloc (name_len);
1037        while (name        while (name
1038               && (status = gethostname (name, name_len)) == 0               && (status = gethostname (name, name_len)) == 0
# Line 981  util_localname () Line 1045  util_localname ()
1045          {          {
1046            syslog (LOG_CRIT, _("Can't find out my own hostname"));            syslog (LOG_CRIT, _("Can't find out my own hostname"));
1047            exit (1);            exit (1);
1048          }          }
1049    
1050        hp = gethostbyname (name);        hp = gethostbyname (name);
1051        if (hp)        if (hp)
1052          {          {
1053            struct in_addr inaddr;            struct in_addr inaddr;
1054            inaddr.s_addr = *(unsigned int*)hp->h_addr;            inaddr.s_addr = *(unsigned int *) hp->h_addr;
1055            hp = gethostbyaddr ((const char *)&inaddr,            hp = gethostbyaddr ((const char *) &inaddr,
1056                                sizeof (struct in_addr), AF_INET);                                sizeof (struct in_addr), AF_INET);
1057            if (hp)            if (hp)
1058              {              {
1059                free (name);                free (name);
1060                name = strdup ((char *)hp->h_name);                name = strdup ((char *) hp->h_name);
1061              }              }
1062          }          }
1063        localname = name;        localname = name;
# Line 1009  util_wcard_match (const char *string, co Line 1073  util_wcard_match (const char *string, co
1073    const char *p = pattern, *n = string;    const char *p = pattern, *n = string;
1074    char c;    char c;
1075    
1076    for (;(c = *p++) != '\0' && *n; n++)    for (; (c = *p++) != '\0' && *n; n++)
1077      {      {
1078        switch (c)        switch (c)
1079          {          {
# Line 1071  util_uidvalidity (mailbox_t smbox, unsig Line 1135  util_uidvalidity (mailbox_t smbox, unsig
1135      smbox = mbox;      smbox = mbox;
1136    return mailbox_uidvalidity (smbox, uidvp);    return mailbox_uidvalidity (smbox, uidvp);
1137  }  }
1138    
1139    
1140    void
1141    util_setio (int infile, int outfile)
1142    {
1143      ifile = fdopen (infile, "r");
1144      ofile = fdopen (outfile, "w");
1145      if (!ofile || !ifile)
1146        imap4d_bye (ERR_NO_OFILE);
1147    
1148      setvbuf (ofile, NULL, _IOLBF, 0);
1149    }
1150    
1151    void
1152    util_flush_output ()
1153    {
1154      if (!tls_done)
1155        fflush (ofile);
1156    }
1157    
1158    FILE *
1159    util_is_ofile ()
1160    {
1161      return ofile;
1162    }
1163    
1164    #ifdef WITH_TLS
1165    
1166    int
1167    imap4d_init_tls_server ()
1168    {
1169      sfile =
1170        (gnutls_session) mu_init_tls_server (fileno (ifile), fileno (ofile));
1171      if (!sfile)
1172        return 0;
1173      return 1;
1174    }
1175    
1176    void
1177    imap4d_deinit_tls_server ()
1178    {
1179      mu_deinit_tls_server (sfile);
1180    }
1181    
1182    #endif /* WITH_TLS */

Legend:
Removed from v.1.45  
changed lines
  Added in v.1.46

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26