/*

 * 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);

}