/*
* cipher.c
* This program reads an input file and
enciphers (or deciphers) it, using
* cumulative xor on
its characters.
*/
#include <stdio.h>
#include <string.h>
#define MAX_NAME 80
int main (int argc, char
**argv)
{
FILE
*p_infile; /* The input file. */
char out_name[MAX_NAME]; /* The name of the
output file. */
char *p_suffix; /* The
location of the ".xxx" suffix. */
FILE
*p_outfile; /* The output file. */
int c; /*
The current character read. */
int cum_xor; /*
Cummulative xor of all characters so far. */
int is_ciphered; /* Is the
input file enciphered. */
/* Check the number
of arguments to the program: */
if
(argc < 2)
{
printf ("Usage: %s <input file>\n", argv[0]);
return
(1);
}
/* Open the input
file, specified by argv[1], in binary mode. */
p_infile = fopen (argv[1], "rb");
if
(p_infile == NULL)
{
printf ("Failed to open the input file '%s'.\n", argv[1]);
return
(1);
}
/* If the input
file name has a ".xxx" suffix, it is enciphered and we should
decipher it.
Otherwise, we should encipher it. */
if
((p_suffix = strstr (argv[1], ".xxx")) != NULL)
{
/* Cut the
".xxx" suffix to produce the output filename. */
strncpy (out_name,
argv[1], p_suffix - argv[1]);
out_name[p_suffix
- argv[1]] = '\0';
is_ciphered = 1;
}
else
{
/* Append the ".xxx" suffix to produce the output
filename. */
strcpy (out_name,
argv[1]);
strcat (out_name, ".xxx");
is_ciphered = 0;
}
/* Open the output
file in binary mode. */
p_outfile = fopen (out_name, "wb");
if
(p_outfile == NULL)
{
printf ("Failed to open the output file '%s'.\n",
out_name);
fclose (p_infile);
return
(1);
}
/* Read the input
characters one by one. */
cum_xor = 0;
while
((c = fgetc(p_infile)) != EOF)
{
/* Modify the character by xoring it with the cummulative xor
so far. */
c = c ^ cum_xor;
/* Write it to
the output file. */
fputc (c,
p_outfile);
/* Update the
cummulative xor of the unciphered characters. */
if
(is_ciphered)
cum_xor = cum_xor ^ c;
else
cum_xor = c;
}
printf ("The file '%s' was successfully %s,\noutput was
written to '%s'.\n",
argv[1],
is_ciphered ?
"deciphered"
: "enciphered",
out_name);
/* Close the file.
*/
fclose (p_infile);
fclose (p_outfile);
return
(0);
}