+
+
+/********* base64 stuff ***********/
+
+unsigned char *pack(const char *str, unsigned int *len)
+{
+ int nibbleshift = 4;
+ int first = 1;
+ char *v;
+ static unsigned char buf[MAXLEN+1];
+ int outputpos = -1;
+
+ memset(buf, 0, MAXLEN+1);
+ v = (char *)str;
+ while(*v) {
+ char n = *(v++);
+
+ if((n >= '0') && (n <= '9')) {
+ n -= '0';
+ } else if ((n >= 'A') && (n <= 'F')) {
+ n -= ('A' - 10);
+ } else if ((n >= 'a') && (n <= 'f')) {
+ n -= ('a' - 10);
+ } else {
+ printf("pack type H: illegal hex digit %c", n);
+ n = 0;
+ }
+
+ if (first--) {
+ buf[++outputpos] = 0;
+ } else {
+ first = 1;
+ }
+
+ buf[outputpos] |= (n << nibbleshift);
+ nibbleshift = (nibbleshift + 4) & 7;
+ }
+ *len = outputpos+1;
+ return(buf);
+}
+
+
+/* from php5 sources */
+static char base64_table[] =
+ { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
+ };
+static char base64_pad = '=';
+
+char *base64_encode(const unsigned char *str, int length, int *ret_length)
+{
+ const unsigned char *current = str;
+ char *p;
+ char *result;
+
+ if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
+ if (ret_length != NULL) {
+ *ret_length = 0;
+ }
+ return NULL;
+ }
+
+ result = (char *)calloc((((length + 2) / 3) * 4)+1, sizeof(char));
+ p = result;
+
+ while (length > 2) { /* keep going until we have less than 24 bits */
+ *p++ = base64_table[current[0] >> 2];
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
+ *p++ = base64_table[current[2] & 0x3f];
+
+ current += 3;
+ length -= 3; /* we just handle 3 octets of data */
+ }
+
+ /* now deal with the tail end of things */
+ if (length != 0) {
+ *p++ = base64_table[current[0] >> 2];
+ if (length > 1) {
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[(current[1] & 0x0f) << 2];
+ *p++ = base64_pad;
+ } else {
+ *p++ = base64_table[(current[0] & 0x03) << 4];
+ *p++ = base64_pad;
+ *p++ = base64_pad;
+ }
+ }
+ if (ret_length != NULL) {
+ *ret_length = (int)(p - result);
+ }
+ *p = '\0';
+ return result;