debian/rules: Use `git' potty wrapper.
[qmail] / quote.c
CommitLineData
2117e02e
MW
1#include "stralloc.h"
2#include "str.h"
3#include "quote.h"
4
5/*
6quote() encodes a box as per rfc 821 and rfc 822,
7while trying to do as little quoting as possible.
8no, 821 and 822 don't have the same encoding. they're not even close.
9no special encoding here for bytes above 127.
10*/
11
12static 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
19static int doit(saout,sain)
20stralloc *saout;
21stralloc *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
42int quote_need(s,n)
43char *s;
44unsigned int n;
45{
46 unsigned char uch;
47 int i;
212b6f5d 48 if (!n) return 1;
2117e02e
MW
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
61int quote(saout,sain)
62stralloc *saout;
63stralloc *sain;
64{
65 if (quote_need(sain->s,sain->len)) return doit(saout,sain);
66 return stralloc_copy(saout,sain);
67}
68
69static stralloc foo = {0};
70
71int quote2(sa,s)
72stralloc *sa;
73char *s;
74{
75 int j;
212b6f5d 76 if (!*s) return stralloc_copys(sa,s);
2117e02e
MW
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}