/*
** Programme de cryptage/decryptage en XOR
** Avantage: on ne pourras pas savoir que c'est un fichier crypte en xor.
** Pour implementer votre propre algo, modifier la fonction xorize_buf
**
** cc -o xorize xorize.c
** Usage : ./xorize source_file dest_file key
** Exemple : ./xorize f1 f2 "ma pass-phrase"
**
** La fonction write() qui sert a ecrire dans un fichier est assez longue.
** J'ecris dans le fichier dest_file par morceaux, chaque morceau etant de
** la taille de la clef. Donc plus votre clef sera longue et moins j'appel-
** lerais cette fonction, donc plus ce sera rapide.
** (Essayez avec un fichier de 2go et une clef d'un octet :P. Enjoy!)
** Autre avantage d'une clef longue : c'est plus difficile a casser.
**
** N'oubliez pas: xor 0,A=A ... donc si le fichier a crypter contient
** des 00 la passphrase y sera en clair si courte ou si beaucoup de 00
** a la suite ;) 
**
** Pour decrypter, en xor c'est pareil: ./xorize crypte decryte key
**
** ATTENTION : Ne mettez pas les memes fichiers de source et destination
** sinon vous allez tout perdre.
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

typedef struct	s_env
{
  int		fd_s;
  int		fd_d;
  char		*key;
  int		keylen;
  char		*buff;
}		env;

void		init_env(env *e, int ac, char **av);
void		xorize_buff(env *e);

int		main(int ac, char **av)
{
  env		e;
  int		rd;
  int		k_idx;

  init_env(&e, ac, av);
  k_idx = 0;
  while ((rd = read(e.fd_s, e.buff, e.keylen)) > 0)
    {
      xorize_buff(&e);
      if (write(e.fd_d, e.buff, e.keylen) == -1)
	{
	  perror("write");
	  exit(1);
	}
    }
  if (rd == -1)
    perror("read");
  else
    printf("Done\n");
  close(e.fd_s);
  close(e.fd_d);
  free(e.buff);
  return (rd ? -1 : 0);
}

void		xorize_buff(env *e)
{
  int		i;

  for (i = 0; i < e->keylen; i++)
    e->buff[i] = e->key[i] ^ e->buff[i];
}

void		init_env(env *e, int ac, char **av)
{
  memset(e, 0, sizeof(*e));
  if (ac > 3)
    {
      e->key = av[3];
      e->keylen = strlen(av[3]);
      if ((e->fd_s = open(av[1], O_RDONLY, 0)) == -1)
	perror(av[1]);
      if ((e->fd_d = open(av[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRWXU)) == -1)
	perror(av[2]);
      if (e->fd_s == -1 || e->fd_d == -1)
	exit(-2);
      if ((e->buff = malloc(e->keylen)) == 0)
	exit(-3);
    }
  else
    {
      fprintf(stderr, "Usage : source_file dest_file key\n");
      exit(-1);
    }
}

