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;
}