Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

base64.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: base64.c,v 1.7.2.1 2004/12/07 03:05:06 pneumatus Exp $
 */

#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include "h.h"

static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64_pad = '=';

int base64_encode(const char *src, size_t srclen, char *target, size_t targetlen)
{
      unsigned char input[3], output[4];
      size_t datalen = 0;
      int i;

      while (srclen > 2) {
            for (i = 0; i < 3; i++) {
                  input[i] = *src++;
                  srclen--;
            }

            output[0] = (input[0] >> 2);
            output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
            output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
            output[3] = (input[2] & 0x3f);

            if ((datalen + 4) > targetlen) {
                  return -1;
            }
            for (i = 0; i < 4; i++) {
                  target[datalen++] = base64_str[output[i]];
            }
      }

      if (srclen) {
            input[0] = input[1] = input[2] = '\0';

            for (i = 0; i < srclen; i++) {
                  input[i] = *src++;
            }

            output[0] = (input[0] >> 2);
            output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
            output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);

            if ((datalen + 4) > targetlen) {
                  return -1;
            }
            for (i = 0; i < 3; i++) {
                  target[datalen++] = (i == 2 && srclen == 1) ? base64_pad : base64_str[output[i]];
            }
            target[datalen++] = base64_pad;
      }

      if (datalen >= targetlen) {
            return -1;
      }
      target[datalen] = '\0';
      return datalen;
}

int base64_decode(const char *src, char *target, size_t targetlen)
{
      int idx = 0, state = 0, c;
      char *pos;

      while ((c = *src++) != '\0') {
            if (IsSpace(c)) {
                  continue;
            }
            if (c == base64_pad) {
                  break;
            }
            if ((pos = strchr(base64_str, c)) == NULL) {
                  return 0;
            }
            if (idx >= targetlen) {
                  return -1;
            }
            switch (state) {
                  case 0:
                        target[idx] = ((pos - base64_str) << 2);
                        state++;
                        break;
                  case 1:
                        target[idx++] = ((pos - base64_str) >> 4);
                        target[idx] = (((pos - base64_str) & 0x0f) << 4);
                        state++;
                        break;
                  case 2:
                        target[idx++] = ((pos - base64_str) >> 2);
                        target[idx] = (((pos - base64_str) & 0x03) << 6);
                        state++;
                        break;
                  case 3:
                        target[idx] |= (pos - base64_str);
                        state = 0;
                        break;
            }
      }

      if (c == base64_pad) {
            c = *src++;
            switch (state) {
                  case 0:
                  case 1:
                        return -1;
                  case 2:
                        while (c != '\0') {
                              if (!IsSpace(c)) {
                                    break;
                              }
                              c = *src++;
                        }
                        if (c != base64_pad) {
                              return -1;
                        }
                        c = *src++;
                  case 3:
                        while (c != '\0') {
                              if (!IsSpace(c)) {
                                    return -1;
                              }
                              c = *src++;
                        }
                        if (target[idx] != '\0') {
                              return -1;
                        }
            }
      }
      else if (state) {
            return -1;
      }
      return idx;
}

Generated by  Doxygen 1.6.0   Back to index