quote.c
changeset 0 068428edee47
equal deleted inserted replaced
-1:000000000000 0:068428edee47
       
     1 #include "stralloc.h"
       
     2 #include "str.h"
       
     3 #include "quote.h"
       
     4 
       
     5 /*
       
     6 quote() encodes a box as per rfc 821 and rfc 822,
       
     7 while trying to do as little quoting as possible.
       
     8 no, 821 and 822 don't have the same encoding. they're not even close.
       
     9 no special encoding here for bytes above 127.
       
    10 */
       
    11 
       
    12 static char ok[128] = {
       
    13  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
       
    14 ,0,7,0,7,7,7,7,7,0,0,7,7,0,7,7,7 ,7,7,7,7,7,7,7,7,7,7,0,0,0,7,0,7
       
    15 ,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 ,7,7,7,7,7,7,7,7,7,7,7,0,0,0,7,7
       
    16 ,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 ,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0
       
    17 } ;
       
    18 
       
    19 static int doit(saout,sain)
       
    20 stralloc *saout;
       
    21 stralloc *sain;
       
    22 {
       
    23  char ch;
       
    24  int i;
       
    25  int j;
       
    26 
       
    27  if (!stralloc_ready(saout,sain->len * 2 + 2)) return 0;
       
    28  j = 0;
       
    29  saout->s[j++] = '"';
       
    30  for (i = 0;i < sain->len;++i)
       
    31   {
       
    32    ch = sain->s[i];
       
    33    if ((ch == '\r') || (ch == '\n') || (ch == '"') || (ch == '\\'))
       
    34      saout->s[j++] = '\\';
       
    35    saout->s[j++] = ch;
       
    36   }
       
    37  saout->s[j++] = '"';
       
    38  saout->len = j;
       
    39  return 1;
       
    40 }
       
    41 
       
    42 int quote_need(s,n)
       
    43 char *s;
       
    44 unsigned int n;
       
    45 {
       
    46  unsigned char uch;
       
    47  int i;
       
    48  if (!n) return 1;
       
    49  for (i = 0;i < n;++i)
       
    50   {
       
    51    uch = s[i];
       
    52    if (uch >= 128) return 1;
       
    53    if (!ok[uch]) return 1;
       
    54   }
       
    55  if (s[0] == '.') return 1;
       
    56  if (s[n - 1] == '.') return 1;
       
    57  for (i = 0;i < n - 1;++i) if (s[i] == '.') if (s[i + 1] == '.') return 1;
       
    58  return 0;
       
    59 }
       
    60 
       
    61 int quote(saout,sain)
       
    62 stralloc *saout;
       
    63 stralloc *sain;
       
    64 {
       
    65  if (quote_need(sain->s,sain->len)) return doit(saout,sain);
       
    66  return stralloc_copy(saout,sain);
       
    67 }
       
    68 
       
    69 static stralloc foo = {0};
       
    70 
       
    71 int quote2(sa,s)
       
    72 stralloc *sa;
       
    73 char *s;
       
    74 {
       
    75  int j;
       
    76  if (!*s) return stralloc_copys(sa,s);
       
    77  j = str_rchr(s,'@');
       
    78  if (!stralloc_copys(&foo,s)) return 0;
       
    79  if (!s[j]) return quote(sa,&foo);
       
    80  foo.len = j;
       
    81  if (!quote(sa,&foo)) return 0;
       
    82  return stralloc_cats(sa,s + j);
       
    83 }