chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / quote.c
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 }