diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-12-06 21:51:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-12-06 21:51:01 +0000 |
commit | 6332c8ffbc8f63a8006a3283b95f3e3abae1e8db (patch) | |
tree | 3544b50f45560c21ea14144b99286ae8e4c4a5c1 | |
parent | ea70f894ce5dc62a840a507405724a55e452d033 (diff) | |
download | gnunet-6332c8ffbc8f63a8006a3283b95f3e3abae1e8db.tar.gz gnunet-6332c8ffbc8f63a8006a3283b95f3e3abae1e8db.zip |
-move base64 encoder/decoder to util
-rw-r--r-- | src/include/gnunet_strings_lib.h | 29 | ||||
-rw-r--r-- | src/transport/plugin_transport_smtp.c | 151 | ||||
-rw-r--r-- | src/util/strings.c | 140 |
3 files changed, 169 insertions, 151 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 686be93ad..f93148df5 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -317,6 +317,31 @@ GNUNET_STRINGS_string_to_data (const char *enc, | |||
317 | 317 | ||
318 | 318 | ||
319 | /** | 319 | /** |
320 | * Encode into Base64. | ||
321 | * | ||
322 | * @param data the data to encode | ||
323 | * @param len the length of the input | ||
324 | * @param output where to write the output (*output should be NULL, | ||
325 | * is allocated) | ||
326 | * @return the size of the output | ||
327 | */ | ||
328 | size_t | ||
329 | GNUNET_STRINGS_base64_encode (const char *data, size_t len, char **output); | ||
330 | |||
331 | /** | ||
332 | * Decode from Base64. | ||
333 | * | ||
334 | * @param data the data to encode | ||
335 | * @param len the length of the input | ||
336 | * @param output where to write the output (*output should be NULL, | ||
337 | * is allocated) | ||
338 | * @return the size of the output | ||
339 | */ | ||
340 | size_t | ||
341 | GNUNET_STRINGS_base64_decode (const char *data, size_t len, char **output); | ||
342 | |||
343 | |||
344 | /** | ||
320 | * Parse a path that might be an URI. | 345 | * Parse a path that might be an URI. |
321 | * | 346 | * |
322 | * @param path path to parse. Must be NULL-terminated. | 347 | * @param path path to parse. Must be NULL-terminated. |
@@ -392,8 +417,8 @@ enum GNUNET_STRINGS_FilenameCheck | |||
392 | * | 417 | * |
393 | * @param filename file to check | 418 | * @param filename file to check |
394 | * @param checks checks to perform | 419 | * @param checks checks to perform |
395 | * @return GNUNET_YES if all checks pass, GNUNET_NO if at least one of them | 420 | * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them |
396 | * fails, GNUNET_SYSERR when a check can't be performed | 421 | * fails, #GNUNET_SYSERR when a check can't be performed |
397 | */ | 422 | */ |
398 | int | 423 | int |
399 | GNUNET_STRINGS_check_filename (const char *filename, | 424 | GNUNET_STRINGS_check_filename (const char *filename, |
diff --git a/src/transport/plugin_transport_smtp.c b/src/transport/plugin_transport_smtp.c index fa0c787d1..828a0b884 100644 --- a/src/transport/plugin_transport_smtp.c +++ b/src/transport/plugin_transport_smtp.c | |||
@@ -145,153 +145,6 @@ static unsigned long long rate_limit; | |||
145 | 145 | ||
146 | static GNUNET_CronTime last_transmission; | 146 | static GNUNET_CronTime last_transmission; |
147 | 147 | ||
148 | /** ******************** Base64 encoding ***********/ | ||
149 | |||
150 | #define FILLCHAR '=' | ||
151 | static char *cvt = | ||
152 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; | ||
153 | |||
154 | /** | ||
155 | * Encode into Base64. | ||
156 | * | ||
157 | * @param data the data to encode | ||
158 | * @param len the length of the input | ||
159 | * @param output where to write the output (*output should be NULL, | ||
160 | * is allocated) | ||
161 | * @return the size of the output | ||
162 | */ | ||
163 | static unsigned int | ||
164 | base64_encode (const char *data, unsigned int len, char **output) | ||
165 | { | ||
166 | unsigned int i; | ||
167 | char c; | ||
168 | unsigned int ret; | ||
169 | char *opt; | ||
170 | |||
171 | /* (*output)[ret++] = '\r'; \*/ | ||
172 | #define CHECKLINE \ | ||
173 | if ( (ret % MAX_CHAR_PER_LINE) == 0) { \ | ||
174 | (*output)[ret++] = '\n'; \ | ||
175 | } | ||
176 | ret = 0; | ||
177 | opt = | ||
178 | GNUNET_malloc (2 + | ||
179 | (((len * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + | ||
180 | 2)) / MAX_CHAR_PER_LINE); | ||
181 | /* message must start with \r\n for libesmtp */ | ||
182 | *output = opt; | ||
183 | opt[0] = '\r'; | ||
184 | opt[1] = '\n'; | ||
185 | ret += 2; | ||
186 | for (i = 0; i < len; ++i) | ||
187 | { | ||
188 | c = (data[i] >> 2) & 0x3f; | ||
189 | opt[ret++] = cvt[(int) c]; | ||
190 | CHECKLINE; | ||
191 | c = (data[i] << 4) & 0x3f; | ||
192 | if (++i < len) | ||
193 | c |= (data[i] >> 4) & 0x0f; | ||
194 | opt[ret++] = cvt[(int) c]; | ||
195 | CHECKLINE; | ||
196 | if (i < len) | ||
197 | { | ||
198 | c = (data[i] << 2) & 0x3f; | ||
199 | if (++i < len) | ||
200 | c |= (data[i] >> 6) & 0x03; | ||
201 | opt[ret++] = cvt[(int) c]; | ||
202 | CHECKLINE; | ||
203 | } | ||
204 | else | ||
205 | { | ||
206 | ++i; | ||
207 | opt[ret++] = FILLCHAR; | ||
208 | CHECKLINE; | ||
209 | } | ||
210 | if (i < len) | ||
211 | { | ||
212 | c = data[i] & 0x3f; | ||
213 | opt[ret++] = cvt[(int) c]; | ||
214 | CHECKLINE; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | opt[ret++] = FILLCHAR; | ||
219 | CHECKLINE; | ||
220 | } | ||
221 | } | ||
222 | opt[ret++] = FILLCHAR; | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | #define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\ | ||
227 | :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\ | ||
228 | :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\ | ||
229 | :((a) == '+') ? 62\ | ||
230 | :((a) == '/') ? 63 : -1) | ||
231 | /** | ||
232 | * Decode from Base64. | ||
233 | * | ||
234 | * @param data the data to encode | ||
235 | * @param len the length of the input | ||
236 | * @param output where to write the output (*output should be NULL, | ||
237 | * is allocated) | ||
238 | * @return the size of the output | ||
239 | */ | ||
240 | static unsigned int | ||
241 | base64_decode (const char *data, unsigned int len, char **output) | ||
242 | { | ||
243 | unsigned int i; | ||
244 | char c; | ||
245 | char c1; | ||
246 | unsigned int ret = 0; | ||
247 | |||
248 | #define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\ | ||
249 | GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "ignoring CR/LF\n"); \ | ||
250 | i++; \ | ||
251 | if (i >= len) goto END; \ | ||
252 | } | ||
253 | |||
254 | *output = GNUNET_malloc ((len * 3 / 4) + 8); | ||
255 | #if DEBUG_SMTP | ||
256 | GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, | ||
257 | "base64_decode decoding len=%d\n", len); | ||
258 | #endif | ||
259 | for (i = 0; i < len; ++i) | ||
260 | { | ||
261 | CHECK_CRLF; | ||
262 | if (data[i] == FILLCHAR) | ||
263 | break; | ||
264 | c = (char) cvtfind (data[i]); | ||
265 | ++i; | ||
266 | CHECK_CRLF; | ||
267 | c1 = (char) cvtfind (data[i]); | ||
268 | c = (c << 2) | ((c1 >> 4) & 0x3); | ||
269 | (*output)[ret++] = c; | ||
270 | if (++i < len) | ||
271 | { | ||
272 | CHECK_CRLF; | ||
273 | c = data[i]; | ||
274 | if (FILLCHAR == c) | ||
275 | break; | ||
276 | c = (char) cvtfind (c); | ||
277 | c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); | ||
278 | (*output)[ret++] = c1; | ||
279 | } | ||
280 | if (++i < len) | ||
281 | { | ||
282 | CHECK_CRLF; | ||
283 | c1 = data[i]; | ||
284 | if (FILLCHAR == c1) | ||
285 | break; | ||
286 | |||
287 | c1 = (char) cvtfind (c1); | ||
288 | c = ((c << 6) & 0xc0) | c1; | ||
289 | (*output)[ret++] = c; | ||
290 | } | ||
291 | } | ||
292 | END: | ||
293 | return ret; | ||
294 | } | ||
295 | 148 | ||
296 | /* ********************* the real stuff ******************* */ | 149 | /* ********************* the real stuff ******************* */ |
297 | 150 | ||
@@ -354,7 +207,7 @@ listenAndDistribute (void *unused) | |||
354 | if ((line[pos] == '\r') || (line[pos] == '\n')) | 207 | if ((line[pos] == '\r') || (line[pos] == '\n')) |
355 | break; /* empty line => end of message! */ | 208 | break; /* empty line => end of message! */ |
356 | } | 209 | } |
357 | size = base64_decode (line, pos, &out); | 210 | size = GNUNET_STRINGS_base64_decode (line, pos, &out); |
358 | if (size < sizeof (SMTPMessage)) | 211 | if (size < sizeof (SMTPMessage)) |
359 | { | 212 | { |
360 | GNUNET_GE_BREAK (ectx, 0); | 213 | GNUNET_GE_BREAK (ectx, 0); |
@@ -617,7 +470,7 @@ api_send (GNUNET_TSession * tsession, const void *msg, const unsigned int size, | |||
617 | mp->sender = *core_api->my_identity; | 470 | mp->sender = *core_api->my_identity; |
618 | gm_cls.ebody = NULL; | 471 | gm_cls.ebody = NULL; |
619 | gm_cls.pos = 0; | 472 | gm_cls.pos = 0; |
620 | gm_cls.esize = base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody); | 473 | gm_cls.esize = GNUNET_STRINGS_base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody); |
621 | GNUNET_free (m); | 474 | GNUNET_free (m); |
622 | if (0 == smtp_size_set_estimate (message, gm_cls.esize)) | 475 | if (0 == smtp_size_set_estimate (message, gm_cls.esize)) |
623 | { | 476 | { |
diff --git a/src/util/strings.c b/src/util/strings.c index 85c6a1cc6..70a1160dd 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -1743,4 +1743,144 @@ GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX) | |||
1743 | } | 1743 | } |
1744 | 1744 | ||
1745 | 1745 | ||
1746 | |||
1747 | /** ******************** Base64 encoding ***********/ | ||
1748 | |||
1749 | #define FILLCHAR '=' | ||
1750 | static char *cvt = | ||
1751 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; | ||
1752 | |||
1753 | |||
1754 | /** | ||
1755 | * Encode into Base64. | ||
1756 | * | ||
1757 | * @param data the data to encode | ||
1758 | * @param len the length of the input | ||
1759 | * @param output where to write the output (*output should be NULL, | ||
1760 | * is allocated) | ||
1761 | * @return the size of the output | ||
1762 | */ | ||
1763 | size_t | ||
1764 | GNUNET_STRINGS_base64_encode (const char *data, | ||
1765 | size_t len, | ||
1766 | char **output) | ||
1767 | { | ||
1768 | size_t i; | ||
1769 | char c; | ||
1770 | size_t ret; | ||
1771 | char *opt; | ||
1772 | |||
1773 | ret = 0; | ||
1774 | opt = GNUNET_malloc (2 + (len * 4 / 3) + 8); | ||
1775 | *output = opt; | ||
1776 | for (i = 0; i < len; ++i) | ||
1777 | { | ||
1778 | c = (data[i] >> 2) & 0x3f; | ||
1779 | opt[ret++] = cvt[(int) c]; | ||
1780 | c = (data[i] << 4) & 0x3f; | ||
1781 | if (++i < len) | ||
1782 | c |= (data[i] >> 4) & 0x0f; | ||
1783 | opt[ret++] = cvt[(int) c]; | ||
1784 | if (i < len) | ||
1785 | { | ||
1786 | c = (data[i] << 2) & 0x3f; | ||
1787 | if (++i < len) | ||
1788 | c |= (data[i] >> 6) & 0x03; | ||
1789 | opt[ret++] = cvt[(int) c]; | ||
1790 | } | ||
1791 | else | ||
1792 | { | ||
1793 | ++i; | ||
1794 | opt[ret++] = FILLCHAR; | ||
1795 | } | ||
1796 | if (i < len) | ||
1797 | { | ||
1798 | c = data[i] & 0x3f; | ||
1799 | opt[ret++] = cvt[(int) c]; | ||
1800 | } | ||
1801 | else | ||
1802 | { | ||
1803 | opt[ret++] = FILLCHAR; | ||
1804 | } | ||
1805 | } | ||
1806 | opt[ret++] = FILLCHAR; | ||
1807 | return ret; | ||
1808 | } | ||
1809 | |||
1810 | #define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\ | ||
1811 | :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\ | ||
1812 | :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\ | ||
1813 | :((a) == '+') ? 62\ | ||
1814 | :((a) == '/') ? 63 : -1) | ||
1815 | |||
1816 | |||
1817 | /** | ||
1818 | * Decode from Base64. | ||
1819 | * | ||
1820 | * @param data the data to encode | ||
1821 | * @param len the length of the input | ||
1822 | * @param output where to write the output (*output should be NULL, | ||
1823 | * is allocated) | ||
1824 | * @return the size of the output | ||
1825 | */ | ||
1826 | size_t | ||
1827 | GNUNET_STRINGS_base64_decode (const char *data, | ||
1828 | size_t len, char **output) | ||
1829 | { | ||
1830 | size_t i; | ||
1831 | char c; | ||
1832 | char c1; | ||
1833 | size_t ret = 0; | ||
1834 | |||
1835 | #define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\ | ||
1836 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "ignoring CR/LF\n"); \ | ||
1837 | i++; \ | ||
1838 | if (i >= len) goto END; \ | ||
1839 | } | ||
1840 | |||
1841 | *output = GNUNET_malloc ((len * 3 / 4) + 8); | ||
1842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1843 | "base64_decode decoding len=%d\n", | ||
1844 | (int) len); | ||
1845 | for (i = 0; i < len; ++i) | ||
1846 | { | ||
1847 | CHECK_CRLF; | ||
1848 | if (FILLCHAR == data[i]) | ||
1849 | break; | ||
1850 | c = (char) cvtfind (data[i]); | ||
1851 | ++i; | ||
1852 | CHECK_CRLF; | ||
1853 | c1 = (char) cvtfind (data[i]); | ||
1854 | c = (c << 2) | ((c1 >> 4) & 0x3); | ||
1855 | (*output)[ret++] = c; | ||
1856 | if (++i < len) | ||
1857 | { | ||
1858 | CHECK_CRLF; | ||
1859 | c = data[i]; | ||
1860 | if (FILLCHAR == c) | ||
1861 | break; | ||
1862 | c = (char) cvtfind (c); | ||
1863 | c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); | ||
1864 | (*output)[ret++] = c1; | ||
1865 | } | ||
1866 | if (++i < len) | ||
1867 | { | ||
1868 | CHECK_CRLF; | ||
1869 | c1 = data[i]; | ||
1870 | if (FILLCHAR == c1) | ||
1871 | break; | ||
1872 | |||
1873 | c1 = (char) cvtfind (c1); | ||
1874 | c = ((c << 6) & 0xc0) | c1; | ||
1875 | (*output)[ret++] = c; | ||
1876 | } | ||
1877 | } | ||
1878 | END: | ||
1879 | return ret; | ||
1880 | } | ||
1881 | |||
1882 | |||
1883 | |||
1884 | |||
1885 | |||
1746 | /* end of strings.c */ | 1886 | /* end of strings.c */ |