Back to index

glibc  2.9
Defines | Functions | Variables
base64.c File Reference
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Defines

#define Assert(Cond)   if (!(Cond)) abort()

Functions

int b64_ntop (u_char const *src, size_t srclength, char *target, size_t targsize)
 libresolv_hidden_def (b64_ntop)

Variables

static const char rcsid [] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $"
static const char Base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
static const char Pad64 = '='

Define Documentation

#define Assert (   Cond)    if (!(Cond)) abort()

Definition at line 61 of file base64.c.


Function Documentation

int b64_ntop ( u_char const src,
size_t  srclength,
char *  target,
size_t  targsize 
)

Definition at line 131 of file base64.c.

                                                                             {
       size_t datalength = 0;
       u_char input[3];
       u_char output[4];
       size_t i;

       while (2 < srclength) {
              input[0] = *src++;
              input[1] = *src++;
              input[2] = *src++;
              srclength -= 3;

              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;
              Assert(output[0] < 64);
              Assert(output[1] < 64);
              Assert(output[2] < 64);
              Assert(output[3] < 64);

              if (datalength + 4 > targsize)
                     return (-1);
              target[datalength++] = Base64[output[0]];
              target[datalength++] = Base64[output[1]];
              target[datalength++] = Base64[output[2]];
              target[datalength++] = Base64[output[3]];
       }

       /* Now we worry about padding. */
       if (0 != srclength) {
              /* Get what's left. */
              input[0] = input[1] = input[2] = '\0';
              for (i = 0; i < srclength; 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);
              Assert(output[0] < 64);
              Assert(output[1] < 64);
              Assert(output[2] < 64);

              if (datalength + 4 > targsize)
                     return (-1);
              target[datalength++] = Base64[output[0]];
              target[datalength++] = Base64[output[1]];
              if (srclength == 1)
                     target[datalength++] = Pad64;
              else
                     target[datalength++] = Base64[output[2]];
              target[datalength++] = Pad64;
       }
       if (datalength >= targsize)
              return (-1);
       target[datalength] = '\0';  /* Returned value doesn't count \0. */
       return (datalength);
}

Definition at line 189 of file base64.c.

{
       int tarindex, state, ch;
       char *pos;

       state = 0;
       tarindex = 0;

       while ((ch = *src++) != '\0') {
              if (isspace(ch))     /* Skip whitespace anywhere. */
                     continue;

              if (ch == Pad64)
                     break;

              pos = strchr(Base64, ch);
              if (pos == 0)               /* A non-base64 character. */
                     return (-1);

              switch (state) {
              case 0:
                     if (target) {
                            if ((size_t)tarindex >= targsize)
                                   return (-1);
                            target[tarindex] = (pos - Base64) << 2;
                     }
                     state = 1;
                     break;
              case 1:
                     if (target) {
                            if ((size_t)tarindex + 1 >= targsize)
                                   return (-1);
                            target[tarindex]   |=  (pos - Base64) >> 4;
                            target[tarindex+1]  = ((pos - Base64) & 0x0f)
                                                 << 4 ;
                     }
                     tarindex++;
                     state = 2;
                     break;
              case 2:
                     if (target) {
                            if ((size_t)tarindex + 1 >= targsize)
                                   return (-1);
                            target[tarindex]   |=  (pos - Base64) >> 2;
                            target[tarindex+1]  = ((pos - Base64) & 0x03)
                                                 << 6;
                     }
                     tarindex++;
                     state = 3;
                     break;
              case 3:
                     if (target) {
                            if ((size_t)tarindex >= targsize)
                                   return (-1);
                            target[tarindex] |= (pos - Base64);
                     }
                     tarindex++;
                     state = 0;
                     break;
              default:
                     abort();
              }
       }

       /*
        * We are done decoding Base-64 chars.  Let's see if we ended
        * on a byte boundary, and/or with erroneous trailing characters.
        */

       if (ch == Pad64) {          /* We got a pad char. */
              ch = *src++;         /* Skip it, get next. */
              switch (state) {
              case 0:              /* Invalid = in first position */
              case 1:              /* Invalid = in second position */
                     return (-1);

              case 2:              /* Valid, means one byte of info */
                     /* Skip any number of spaces. */
                     for ((void)NULL; ch != '\0'; ch = *src++)
                            if (!isspace(ch))
                                   break;
                     /* Make sure there is another trailing = sign. */
                     if (ch != Pad64)
                            return (-1);
                     ch = *src++;         /* Skip the = */
                     /* Fall through to "single trailing =" case. */
                     /* FALLTHROUGH */

              case 3:              /* Valid, means two bytes of info */
                     /*
                      * We know this char is an =.  Is there anything but
                      * whitespace after it?
                      */
                     for ((void)NULL; ch != '\0'; ch = *src++)
                            if (!isspace(ch))
                                   return (-1);

                     /*
                      * Now make sure for cases 2 and 3 that the "extra"
                      * bits that slopped past the last full byte were
                      * zeros.  If we don't check them, they become a
                      * subliminal channel.
                      */
                     if (target && target[tarindex] != 0)
                            return (-1);
              }
       } else {
              /*
               * We ended by seeing the end of the string.  Make sure we
               * have no partial bytes lying around.
               */
              if (state != 0)
                     return (-1);
       }

       return (tarindex);
}

Here is the call graph for this function:


Variable Documentation

const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" [static]

Definition at line 63 of file base64.c.

const char Pad64 = '=' [static]

Definition at line 65 of file base64.c.

const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $" [static]

Definition at line 44 of file base64.c.