/********************************************************************
 *  PROGRAMA: Practica.c                                            *
 *  AUTORES:  Victor Manuel Herrero Rodriguez                       *
 *            Javier Acosta Molinero                                *
 *  PRACTICA DE SISTEMAS OPERATIVOS - 3º DE ESTADISTICA             *
*********************************************************************/

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include "rshmem.h"

#define EVER (;;)        /* Para bucle infinito */

#define NOM 14
#define TAM 50

typedef struct {         /* Estructura donde se guardan los nombres */
    char nombre[NOM];     /* y tamaños de los ficheros               */
    long tam;
    }TAB;


/********************************************************************
 *                       FUNCION PRINCIPAL                          *
 * DESCRIPCION: Recibe dos argumentos                               *
 *      - Nombre del archivo que contendra todos los ficheros.      *
 *      - Directorio donde estan los ficheros.                      *
 * Realiza dos procesos en concurrencia mediante memoria compartida *
*********************************************************************/

main(int argc,char *argv[])
{
  char *n1,*n2,*n3,*MarcaFin;  /* Punteros a memoria compartida */

  TAB *tmem[TAM];               /* Puntero a tabla de ficheros   */

  FILE *tabla;                 /* Variables que controlan los ficheros */
  FILE *fich_l;
  char d;

  DIR *dact;                   /* Estructuras y variables que controlan */
  struct dirent *dp;           /* el directorio y sus ficheros          */
  struct stat buf;
  int dficheros;  

  int k;                     /* Contador */
  char *archivo;            /* Archivo donde alojar los ficheros */
  
  char permisos[3];
  permisos[0]= 'x';
  permisos[1]= 'w'; 
  permisos[2]= 'r';
  

  /* Se comprueban los parametros introducidos */
  if(argc!=2){
    fprintf(stderr, "\nForma de uso: %s Nombre_archivo \n",argv[0]);
    exit(-1);
  }

   
  if (!crearMemoria()){         /* Se crea memoria compartida */
      fprintf(stderr, "error de crearMemoria\n");
      exit(-1);     
  }

  n1=memoria;                  /* Se asignan direcciones de memoria a los */
  n2=n1+sizeof(char);          /* punteros                                */
  n3=n2+sizeof(char);
  MarcaFin=n3+sizeof(char);
  archivo=MarcaFin+sizeof(char);
  tmem[0]=(TAB *)archivo+14*sizeof(char);
  for(k=1;k<TAM;k++)
    tmem[k]=tmem[k-1]+sizeof(TAB);

  *n1=0;      /* Inicializacion de variables en memoria compartida */
  *n2=0;
  *n3=TAM;
  *MarcaFin=NULL;
  
  /* Copiamos argumentos */
  strcpy(archivo,argv[1]);
    
 if(0!=fork()){               /* PROCESO PADRE */
    dact = opendir("."); /* Apertura del directorio */
  


  while(NULL != (dp = readdir(dact)))  /* Leemos el contenido del */
  {                                    /* directorio              */
    
    dficheros = stat(dp->d_name,&buf); /* Informacion del fichero */
    
    /* Omitimos ficheros que no interesan y subdirectorios */ 
    if((dficheros != -1 && (buf.st_mode & S_IFMT) != S_IFDIR)
       && ( dp->d_name[0] !='.') && (strcmp(archivo,dp->d_name)!= 0)
       && (strcmp("practica",dp->d_name)!= 0))
    {
      strcpy(tmem[(*n1)]->nombre,dp->d_name); /* Creamos tabla en */
      tmem[(*n1)]->tam = buf.st_size;         /* memoria */
      
      TP TP TP
      printf("\n%-14s %8li",dp->d_name,buf.st_size);
      printf("\t");
      
      /* Obtenemos los permisos del fichero */
      for(k=0;k<9;k++)
      {
        if(buf.st_mode & (0400>> k))
           printf("%c",permisos[(8-k)%3]);
        else
          printf("-");
      }

      TP TP TP
      (*n1)++;
    }   
  }
  closedir(dact);
  printf("\n");
  *n3=*n1;     /*guardamos el numero de ficheros leidos */

  while((*MarcaFin)!='F');  /*espera que termine el PROCESO HIJO */

 
  if (!eliminarMemoria())  /* Eliminamos memoria compartida */
         fprintf(stderr, "error de eliminarMemoria\n");
         exit(0);
  }

 else{                 /* PROCESO HIJO */

  tabla=fopen(archivo,"w");
  for EVER {                  /* Repetir mientras existan ficheros */
  while((*n2)>=(*n1))      /* Espero a tener algun nombre de fichero nuevo */  
   if((*n2)==(*n3)){          /* El proceso hijo a terminado */
     *MarcaFin='F'; 
     fclose(tabla);
     exit(0);
   }

   fprintf(tabla,"\n\n");
   fich_l=fopen(tmem[(*n2)]->nombre,"r"); 
   fscanf(fich_l,"%c",&d);

   while(!feof(fich_l))        /* Copiamos el fichero al archivo */
    {
     fprintf(tabla,"%c",d);
     fscanf(fich_l,"%c",&d);
    }
    fclose(fich_l);
    (*n2)++; 
   }  
 } 
}