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