|
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 } |