-rw-r--r-- | rsync/base64.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/rsync/base64.c b/rsync/base64.c new file mode 100644 index 0000000..cbe7a8c --- a/dev/null +++ b/rsync/base64.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- | ||
2 | * | ||
3 | * librsync -- the library for network deltas | ||
4 | * $Id$ | ||
5 | * | ||
6 | * Copyright (C) 2000 by Martin Pool <mbp@samba.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public License | ||
10 | * as published by the Free Software Foundation; either version 2.1 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <config_rsync.h> | ||
25 | |||
26 | #include <string.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <stdio.h> | ||
29 | |||
30 | #include "rsync.h" | ||
31 | |||
32 | /* | ||
33 | * Decode a base64 string in-place - simple and slow algorithm | ||
34 | * | ||
35 | * See RFC1521 for the specification of base64. | ||
36 | */ | ||
37 | size_t rs_unbase64(char *s) | ||
38 | { | ||
39 | char const *b64 = | ||
40 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
41 | int bit_offset, byte_offset, idx, i, n; | ||
42 | unsigned char *d = (unsigned char *) s; | ||
43 | char *p; | ||
44 | |||
45 | n = i = 0; | ||
46 | |||
47 | while (*s && (p = strchr(b64, *s))) { | ||
48 | idx = (int) (p - b64); | ||
49 | byte_offset = (i * 6) / 8; | ||
50 | bit_offset = (i * 6) % 8; | ||
51 | d[byte_offset] &= ~((1 << (8 - bit_offset)) - 1); | ||
52 | if (bit_offset < 3) { | ||
53 | d[byte_offset] |= (idx << (2 - bit_offset)); | ||
54 | n = byte_offset + 1; | ||
55 | } else { | ||
56 | d[byte_offset] |= (idx >> (bit_offset - 2)); | ||
57 | d[byte_offset + 1] = 0; | ||
58 | d[byte_offset + 1] |= (idx << (8 - (bit_offset - 2))) & 0xFF; | ||
59 | n = byte_offset + 2; | ||
60 | } | ||
61 | s++; | ||
62 | i++; | ||
63 | } | ||
64 | |||
65 | return n; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Encode a buffer as base64 - simple and slow algorithm. | ||
70 | */ | ||
71 | void | ||
72 | rs_base64(unsigned char const *buf, int n, char *out) | ||
73 | { | ||
74 | char const *b64 = | ||
75 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
76 | int bytes, i; | ||
77 | |||
78 | /* work out how many bytes of output there are */ | ||
79 | bytes = ((n * 8) + 5) / 6; | ||
80 | |||
81 | for (i = 0; i < bytes; i++) { | ||
82 | int byte = (i * 6) / 8; | ||
83 | int bit = (i * 6) % 8; | ||
84 | |||
85 | if (bit < 3) { | ||
86 | if (byte >= n) | ||
87 | abort(); | ||
88 | *out = b64[(buf[byte] >> (2 - bit)) & 0x3F]; | ||
89 | } else { | ||
90 | if (byte + 1 == n) { | ||
91 | *out = b64[(buf[byte] << (bit - 2)) & 0x3F]; | ||
92 | } else { | ||
93 | *out = b64[(buf[byte] << (bit - 2) | | ||
94 | buf[byte + 1] >> (10 - bit)) & 0x3F]; | ||
95 | } | ||
96 | } | ||
97 | out++; | ||
98 | } | ||
99 | *out = 0; | ||
100 | } | ||
101 | |||