]> git.ipfire.org Git - people/ms/dma.git/blobdiff - base64.c
Merge pull request #57 from mtremer/better-tls
[people/ms/dma.git] / base64.c
index 610aa3c313827d1210b5b883523bec6744045f02..663763e8c773e4b4e98eb45f077de80206c1667e 100644 (file)
--- a/base64.c
+++ b/base64.c
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $DragonFly: src/libexec/dma/base64.c,v 1.1 2008/02/02 18:20:51 matthias Exp $
  */
 
 #include <stdlib.h>
 #include <string.h>
 
-int base64_encode(const void *data, int size, char **str);
+#include "dma.h"
 
 static char base64_chars[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
+static int
+pos(char c)
+{
+       char *p;
+       for (p = base64_chars; *p; p++)
+               if (*p == c)
+                       return p - base64_chars;
+       return -1;
+}
+
+
 int
 base64_encode(const void *data, int size, char **str)
 {
@@ -79,3 +88,48 @@ base64_encode(const void *data, int size, char **str)
     return strlen(s);
 }
 
+#define DECODE_ERROR 0xffffffff
+
+static unsigned int
+token_decode(const char *token)
+{
+       int i;
+       unsigned int val = 0;
+       int marker = 0;
+       if (strlen(token) < 4)
+               return DECODE_ERROR;
+       for (i = 0; i < 4; i++) {
+               val *= 64;
+               if (token[i] == '=')
+                       marker++;
+               else if (marker > 0)
+                       return DECODE_ERROR;
+               else
+                       val += pos(token[i]);
+       }
+       if (marker > 2)
+               return DECODE_ERROR;
+       return (marker << 24) | val;
+}
+
+int
+base64_decode(const char *str, void *data)
+{
+       const char *p;
+       unsigned char *q;
+
+       q = data;
+       for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
+               unsigned int val = token_decode(p);
+               unsigned int marker = (val >> 24) & 0xff;
+               if (val == DECODE_ERROR)
+                       return -1;
+               *q++ = (val >> 16) & 0xff;
+               if (marker < 2)
+                       *q++ = (val >> 8) & 0xff;
+               if (marker < 1)
+                       *q++ = val & 0xff;
+       }
+       return q - (unsigned char *) data;
+}
+