Back to index

citadel  8.12
Defines | Typedefs | Functions | Variables
base64.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

Go to the source code of this file.

Defines

#define TRUE   1
#define FALSE   0
#define LINELEN   72 /* Encoded line length (max 76) */

Typedefs

typedef unsigned char byte

Functions

static int inbuf (void)
static int inchar (void)
static void ochar (int c)
static void encode (void)
static int insig (void)
static void decode (void)
static void usage (char *pname)
int main (int argc, char *argv[])

Variables

FILE * fi
FILE * fo
static byte iobuf [256]
static int iolen = 0
static int iocp = 256
static int ateof = FALSE
static byte dtable [256]
static int linelength = 0
static char eol [] = "\r\n"
static int errcheck = TRUE

Define Documentation

#define FALSE   0

Definition at line 22 of file base64.c.

#define LINELEN   72 /* Encoded line length (max 76) */

Definition at line 24 of file base64.c.

#define TRUE   1

Definition at line 21 of file base64.c.


Typedef Documentation

typedef unsigned char byte

Definition at line 26 of file base64.c.


Function Documentation

static void decode ( void  ) [static]

Definition at line 166 of file base64.c.

{
    int i;

    for (i = 0; i < 255; i++) {
       dtable[i] = 0x80;
    }
    for (i = 'A'; i <= 'Z'; i++) {
        dtable[i] = 0 + (i - 'A');
    }
    for (i = 'a'; i <= 'z'; i++) {
        dtable[i] = 26 + (i - 'a');
    }
    for (i = '0'; i <= '9'; i++) {
        dtable[i] = 52 + (i - '0');
    }
    dtable['+'] = 62;
    dtable['/'] = 63;
    dtable['='] = 0;

    /*CONSTANTCONDITION*/
    while (TRUE) {
       byte a[4], b[4], o[3];

       for (i = 0; i < 4; i++) {
           int c = insig();

           if (c == EOF) {
              if (errcheck && (i > 0)) {
                    fprintf(stderr, "Input file incomplete.\n");
                  exit(1);
              }
              return;
           }
           if (dtable[c] & 0x80) {
              if (errcheck) {
                    fprintf(stderr, "Illegal character '%c' in input file.\n", c);
                  exit(1);
              }
              /* Ignoring errors: discard invalid character. */
              i--;
              continue;
           }
           a[i] = (byte) c;
           b[i] = (byte) dtable[c];
       }
       o[0] = (b[0] << 2) | (b[1] >> 4);
       o[1] = (b[1] << 4) | (b[2] >> 2);
       o[2] = (b[2] << 6) | b[3];
        i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
       if (fwrite(o, i, 1, fo) == EOF) {
           exit(1);
       }
       if (i < 3) {
           return;
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void encode ( void  ) [static]

Definition at line 93 of file base64.c.

{
    int i, hiteof = FALSE;

    /* Fill dtable with character encodings.  */

    for (i = 0; i < 26; i++) {
        dtable[i] = 'A' + i;
        dtable[26 + i] = 'a' + i;
    }
    for (i = 0; i < 10; i++) {
        dtable[52 + i] = '0' + i;
    }
    dtable[62] = '+';
    dtable[63] = '/';

    while (!hiteof) {
       byte igroup[3], ogroup[4];
       int c, n;

       igroup[0] = igroup[1] = igroup[2] = 0;
       for (n = 0; n < 3; n++) {
           c = inchar();
           if (c == EOF) {
              hiteof = TRUE;
              break;
           }
           igroup[n] = (byte) c;
       }
       if (n > 0) {
           ogroup[0] = dtable[igroup[0] >> 2];
           ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
           ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
           ogroup[3] = dtable[igroup[2] & 0x3F];

            /* Replace characters in output stream with "=" pad
              characters if fewer than three characters were
              read from the end of the input stream. */

           if (n < 3) {
                ogroup[3] = '=';
              if (n < 2) {
                    ogroup[2] = '=';
              }
           }
           for (i = 0; i < 4; i++) {
              ochar(ogroup[i]);
           }
       }
    }
    if (fputs(eol, fo) == EOF) {
       exit(1);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int inbuf ( void  ) [static]

Definition at line 41 of file base64.c.

{
    int l;

    if (ateof) {
       return FALSE;
    }
    l = fread(iobuf, 1, sizeof iobuf, fi);     /* Read input buffer */
    if (l <= 0) {
       if (ferror(fi)) {
           exit(1);
       }
       ateof = TRUE;
       return FALSE;
    }
    iolen = l;
    iocp = 0;
    return TRUE;
}

Here is the caller graph for this function:

static int inchar ( void  ) [static]

Definition at line 63 of file base64.c.

{
    if (iocp >= iolen) {
       if (!inbuf()) {
         return EOF;
       }
    }

    return iobuf[iocp++];
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int insig ( void  ) [static]

Definition at line 150 of file base64.c.

{
    int c;

    /*CONSTANTCONDITION*/
    while (TRUE) {
       c = inchar();
        if (c == EOF || (c > ' ')) {
           return c;
       }
    }
    /*NOTREACHED*/
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 
)

Warning! On systems which distinguish text mode and binary I/O (MS-DOS, Macintosh, etc.) the modes in these open statements will have to be made conditional based upon whether an encode or decode is being done, which will have to be specified earlier. But it's worse: if input or output is from standard input or output, the mode will have to be changed on the fly, which is generally system and compiler dependent. 'Twasn't me who couldn't conform to Unix CR/LF convention, so don't ask me to write the code to work around Apple and Microsoft's incompatible standards.

Definition at line 245 of file base64.c.

{
    int i, f = 0, decoding = FALSE;
    char *cp, opt;

    fi = stdin;
    fo = stdout;

    for (i = 1; i < argc; i++) {
       cp = argv[i];
        if (*cp == '-') {
           opt = *(++cp);
           if (islower(opt)) {
              opt = toupper(opt);
           }
           switch (opt) {

                case 'D':             /* -D  Decode */
                  decoding = TRUE;
                  break;

                case 'E':             /* -E  Encode */
                  decoding = FALSE;
                  break;

                case 'N':             /* -N  Suppress error checking */
                  errcheck = FALSE;
                  break;

                case 'U':             /* -U  Print how-to-call information */
                case '?':
                  usage(argv[0]);
                  return 0;
          }
       } else {
           switch (f) {

              case 0:
                    if (strcmp(cp, "-") != 0) {
                        if ((fi = fopen(cp, "r")) == NULL) {
                            fprintf(stderr, "Cannot open input file %s\n", cp);
                         return 2;
                     }
                  }
                  f++;
                  break;

              case 1:
                    if (strcmp(cp, "-") != 0) {
                        if ((fo = fopen(cp, "w")) == NULL) {
                            fprintf(stderr, "Cannot open output file %s\n", cp);
                         return 2;
                     }
                  }
                  f++;
                  break;

              default:
                    fprintf(stderr, "Too many file names specified.\n");
                  usage(argv[0]);
                  return 2;
           }
       }
    }

    if (decoding) {
       decode();
    } else {
       encode();
    }
    return 0;
}

Here is the call graph for this function:

static void ochar ( int  c) [static]

Definition at line 77 of file base64.c.

{
    if (linelength >= LINELEN) {
       if (fputs(eol, fo) == EOF) {
           exit(1);
       }
       linelength = 0;
    }
    if (putc(((byte) c), fo) == EOF) {
       exit(1);
    }
    linelength++;
}

Here is the caller graph for this function:

static void usage ( char *  pname) [static]

Definition at line 227 of file base64.c.

{
    fprintf(stderr, "%s  --  Encode/decode file as base64.  Call:\n", pname);
    fprintf(stderr,
    "            %s [-e[ncode] / -d[ecode]] [-n] [infile] [outfile]\n", pname);
    fprintf(stderr, "\n");
    fprintf(stderr, "Options:\n");
    fprintf(stderr, "           -D         Decode base64 encoded file\n");
    fprintf(stderr, "           -E         Encode file into base64\n");
    fprintf(stderr, "           -N         Ignore errors when decoding\n");
    fprintf(stderr, "           -U         Print this message\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "by John Walker\n");
    fprintf(stderr, "   WWW:    http://www.fourmilab.ch/\n");
}

Here is the caller graph for this function:


Variable Documentation

int ateof = FALSE [static]

Definition at line 33 of file base64.c.

byte dtable[256] [static]

Definition at line 34 of file base64.c.

char eol[] = "\r\n" [static]

Definition at line 36 of file base64.c.

int errcheck = TRUE [static]

Definition at line 37 of file base64.c.

FILE* fi

Definition at line 28 of file base64.c.

FILE* fo

Definition at line 29 of file base64.c.

byte iobuf[256] [static]

Definition at line 30 of file base64.c.

int iocp = 256 [static]

Definition at line 32 of file base64.c.

int iolen = 0 [static]

Definition at line 31 of file base64.c.

int linelength = 0 [static]

Definition at line 35 of file base64.c.