#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "arch.h"

#define START_P 8 /* Starting file position of the packet area */

int put_in_a_file(char *fname, struct pack *l_pack, u_int32_t nop){
  struct pack_info *inf_vect;
  struct pack *l_pack_aux;
  int fd;
  u_int32_t info_offset = 0;
  
  fd = open(fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
  if(fd < 0){
    printf("Ooops! Couldn't open a file...\n");
    return -1;
  }
 
  inf_vect = (struct pack_info *)malloc(sizeof(struct pack_info)*nop);
  
  write(fd,&nop,4);
  write(fd,&info_offset,4);
 
  while(l_pack != NULL){
    memcpy(inf_vect[l_pack->id-1].layer,l_pack->layer,MAX_LAYER*2);
    inf_vect[l_pack->id-1].size = l_pack->psize;
    inf_vect[l_pack->id-1].offset = info_offset;
    info_offset += write(fd,l_pack->data,l_pack->psize);
    l_pack_aux = l_pack;
    l_pack = l_pack->next;
    free(l_pack_aux);
  }
  info_offset += START_P;
  write(fd,inf_vect,sizeof(struct pack_info)*nop);
  lseek(fd,4,SEEK_SET);
  write(fd,&info_offset,4);
  close(fd);
  return 0;
}

struct pack_vect *load_packs(char *fname, u_int32_t *nopa){
  struct pack_info *the_table = NULL;
  struct pack_vect *packs = NULL;
  u_int32_t nop;
  u_int32_t p_info_off;
  int fd,i;
  char *h;
 
  fd = open(fname,O_RDONLY);
  if(fd < 0){
    printf("Ooops! Couldn't open the file...\n");
    *nopa = 0;
    return NULL;
  }
  read(fd,&nop,4);
  read(fd,&p_info_off,4);
  packs     = (struct pack_vect *)malloc(sizeof(struct pack_vect)*nop);
  the_table = (struct pack_info *)malloc(sizeof(struct pack_info)*nop);
  lseek(fd,p_info_off,SEEK_SET);
  read(fd,the_table,sizeof(struct pack_info)*nop);
  for(i=0;i<nop;i++){
    packs[i].id = i+1;
    memcpy(packs[i].layer,the_table[i].layer,MAX_LAYER*2);
    packs[i].psize = the_table[i].size;
    lseek(fd,the_table[i].offset+START_P,SEEK_SET);
    read(fd,packs[i].data,the_table[i].size);
  }
  close(fd);
  free(the_table);
  *nopa = nop;
  return packs;
}

void show_buffs(u_char *buff, int size){
  int i;

  for(i=0;i<size;i+=2){
    printf("%c%.2x%.2x",i%16?' ':'\n',buff[i],buff[i+1]);
  }
  printf("\n");
}

void show_packs(struct pack_vect *packs, int nop){
  int i,j;

  for(i=0;i<nop;i++){
    printf("\n\nID:		%d\n",packs[i].id);
    printf("LAYER:	");
    for(j=0;j<MAX_LAYER;j++){
      printf("(%d)",packs[i].layer[j]);
    }
    printf("\nSize:	%d\nPacket\n",packs[i].psize);
    for(j=0;j<packs[i].psize/8;j+=2){
      printf("%c%.2x%.2x",j%16?' ':'\n',packs[i].data[j],packs[i].data[j+1]);
    }
  }
  printf("\n");
}

void show_packs2(struct pack_vect *packs, int nop){
  int i,j,k,l;
 
  for(i=0;i<nop;i++){
    printf("\n\nID:	%d\n",packs[i].id);
    printf("LAYER:	");
    for(j=0;j<MAX_LAYER;j++){
      printf("(%d)",packs[i].layer[j]);
    }
    printf("\nSize:	%d\nPacket\n",packs[i].psize);
    for(j=0;j<packs[i].psize/8;j+=2){
      if((j%16==0) && (j!=0)){
        printf("\t");
	for(k=j-16;k<j;k++)
	  printf("%c",(packs[i].data[k]>31&&packs[i].data[k]<127)?(packs[i].data[k]):('.'));
	printf("\n");
      }
      printf(" %.2x%.2x",packs[i].data[j],packs[i].data[j+1]);
    }
    for(l=0;l<16-j%16;l+=2)
      printf("     ");
    printf("\t");
    for(l=k;l<packs[i].psize/8;l++)
      printf("%c",(packs[i].data[l]>31&&packs[i].data[l]<127)?(packs[i].data[l]):('.'));
  }
  printf("\n");
}

