Download | Plain Text | Line Numbers


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "cipher.h"
 
#ifdef DEBUG
# include "hexdump.h"
#endif
 
#define BLOCKSIZE     8192
#define PERL_SHEBANG "#!/usr/bin/perl\n"
#define PERL_MODULE  "use Confixx::Filter;\n"
 
static const char *me;
 
void usage()
{
  fprintf(stderr, "Usage: %s [options] <file>\n", me);
  fprintf(stderr, "\nOptions:\n");
  fprintf(stderr, "  -d\tdecode mode\n");
  fprintf(stderr, "  -e\tencode mode\n");
  fprintf(stderr, "  -k\tdon't prepend hash key in decode mode\n");
  fprintf(stderr, "  -h\tthis help\n");
  exit(EXIT_FAILURE);
}
 
int main(int argc, char *argv[])
{
  short encode = 0, stripped = 0, hashkey = 1;
  char *filename = NULL;
  int opt;
 
  me = argv[0];
 
  while ((opt = getopt(argc, argv, "hked")) != -1)
  {
    switch(opt)
    {
      case 'e':
        encode  = 1;
        hashkey = 0;
        break;
      case 'd':
        break;
      case 'k':
        hashkey = 0;
        break;
      case 'h':
      default:
        usage();
        break;
    }
  }
  argv += optind;
 
  if (argv)
    filename = *argv;
 
  if (!filename)
    usage();
 
#ifdef DEBUG
  fprintf(stderr, "[DEBUG] Mode: %s\n", (encode) ? "encode" : "decode");
  fprintf(stderr, "[DEBUG] filename: %s\n", filename);
#endif
 
  FILE *fp = stdin;
  if (strcmp(filename, "-") == 0)
    filename = NULL;
  if (filename != NULL && (fp = fopen(filename, "r")) == NULL)
  {
    fprintf(stderr, "Unable to open input file '%s'", filename);
    if (errno)
      fprintf(stderr, ": %s", strerror(errno));
    fprintf(stderr, "\n");
    exit(EXIT_FAILURE);
  }
 
  /* allocate buffer for decrypted stuff */
  char out[BLOCKSIZE];
 
  /* cipher */
  ctx_t cipher;
  memset(&cipher, 0, sizeof(ctx_t)); //TODO
  int ret = CipherInit(&cipher);
  if (ret != 256)
  {
    fprintf(stderr, "Unexpected return value of CipherInit()\n");
    exit(EXIT_FAILURE);
  }
#ifdef DEBUG
  fprintf(stderr, "[DEBUG] CipherInit()=%d\n", ret);
#endif
 
  /* set pointer to output buffer */
  cipher.out = out;
 
  /* some sanity checks */
  assert(cipher.out  == out);
  assert(cipher.ret  == 0);
  assert(cipher.off1 == 0);
  assert(cipher.off2 == 0);
  assert(cipher.prepend_hashkey == 1);
 
  /* let CipherUpdate don't prepend a hashkey */
  cipher.prepend_hashkey = hashkey;
 
  /* allocate input buffer */
  char in[BLOCKSIZE];
 
  if (encode)
  {
    printf(PERL_SHEBANG);
    printf(PERL_MODULE);
  }
 
  while(!feof(fp))
  {
    /* read at most BLOCKSIZE - 1 bytes:
     *  - 1 char ("#"-char) will be prepended in decode mode during
     *    first call of CipherUpdate()
     */
    size_t in_len = fread(in, sizeof(char), BLOCKSIZE - 1, fp);
    assert(in_len == (uint32_t)in_len);
    if (ferror(fp))
    {
      fprintf(stderr, "Error while reading input file");
      if (errno)
        fprintf(stderr, ": %s", strerror(errno));
      fprintf(stderr, "\n");
      if (filename != NULL)
        fclose(fp);
      exit(EXIT_FAILURE);
    }
    in[in_len] = '\0';
 
#ifdef DEBUG
    fprintf(stderr, "[DEBUG] read %zu bytes from input file\n", in_len);
#endif
 
    char *inptr = in;
    if (!encode && !stripped)
    {
      if (strncmp(inptr, PERL_SHEBANG, sizeof(PERL_SHEBANG) - 1) == 0)
        inptr += sizeof(PERL_SHEBANG) - 1;
      if (strncmp(inptr, PERL_MODULE, sizeof(PERL_MODULE) - 1) == 0)
        inptr += sizeof(PERL_MODULE) - 1;
      in_len -= inptr - in;
    }
    stripped = 1;
 
    uint32_t out_len = CipherUpdate(&cipher, inptr, in_len);
#ifdef DEBUG
    fprintf(stderr, "[DEBUG] CipherUpdate()=%u\n", out_len);
#endif
    /* we don't need one extra byte to terminate the buffer
     * as fwrite has a size parameter
     */
    assert(out_len <= BLOCKSIZE);
 
#ifdef DEBUG
    fprintf(stderr, "[DEBUG] Output:\n");
#endif
    fwrite(out, out_len, sizeof(char), stdout);
  }
 
  if (filename != NULL)
    fclose(fp);
  return 0;
}