quote.c - rohrpost - A commandline mail client to change the world as we see it.
(HTM) git clone git://r-36.net/rohrpost
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
quote.c (2212B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "ind.h"
12
13 char *
14 qpenc(char *str, int len, int ishdr)
15 {
16 char *ret, add[6];
17 int i, rlen, alen, llen;
18
19 ret = NULL;
20 for (i = 0, llen = 0, rlen = 0; i < len; i++) {
21 if (str[i] < 0x20 || str[i] > 0x7E)
22 snprintf(add, sizeof(add), "=%02x", str[i] & 0xFF);
23 else {
24 switch(str[i]) {
25 case ' ':
26 if (ishdr) {
27 add[0] = '_';
28 add[1] = '\0';
29 break;
30 }
31 case '?':
32 case '_':
33 case '=':
34 case '(':
35 case ')':
36 case '<':
37 case '>':
38 case '@':
39 case ',':
40 case ';':
41 case '\\':
42 case '"':
43 case '/':
44 case '[':
45 case ']':
46 snprintf(add, sizeof(add), "=%02x",
47 str[i] & 0xFF);
48 break;
49 case '\n':
50 if (i > 0 && strchr("\t\r\v\f", str[i-1])) {
51 add[0] = '=';
52 add[1] = str[i];
53 add[2] = '\0';
54 break;
55 }
56 default:
57 add[0] = str[i];
58 add[1] = '\0';
59 break;
60 }
61 }
62 alen = strlen(add);
63 if (llen + alen > 76) {
64 ret = memdupcat(ret, rlen, "=\n", 3);
65 rlen += 2;
66 llen = alen;
67 }
68 ret = memdupcat(ret, rlen, add, alen+1);
69 rlen += alen;
70 llen += alen;
71 }
72
73 return ret;
74 }
75
76 char *
77 qpdec(char *str, int *len, int ishdr)
78 {
79 char *ret, add, abuf[3], *eabuf;
80 int i, rlen, pbreak;
81 long nval;
82
83 ret = NULL;
84 for (i = 0, rlen = 0; i < *len; i++) {
85 add = '\0';
86 switch (str[i]) {
87 case '_':
88 add = (ishdr)? ' ' : '_';
89 break;
90 case '=':
91 pbreak = 0;
92 if (str[i+1] == '\r') {
93 i++;
94 pbreak = 1;
95 }
96 if (str[i+1] == '\n') {
97 i++;
98 pbreak = 1;
99 }
100 if (str[i+1] == '\0') {
101 i++;
102 pbreak = 1;
103 }
104 if (pbreak)
105 break;
106
107 memmove(&abuf, &str[i+1], 2);
108 abuf[2] = '\0';
109
110 eabuf = NULL;
111 nval = strtol((char *)&abuf, &eabuf, 16);
112 if (eabuf != NULL && *eabuf != '\0')
113 break;
114
115 add = (char)(nval & 0xFF);
116 i += 2;
117 break;
118 default:
119 /*
120 * Convert CRLF to LF.
121 */
122 if (str[i] == '\r' && i < (*len)-1 && str[i+1] == '\n')
123 add = '\0';
124 else
125 add = str[i];
126 break;
127 }
128 if (add == '\0')
129 continue;
130
131 ret = reallocz(ret, (++rlen)+1, 0);
132 ret[rlen-1] = add;
133 ret[rlen] = '\0';
134 }
135
136 *len = rlen;
137 return ret;
138 }
139