#include "utils.h"
#include <sys/stat.h>
#include <string.h>

//Carrega el fitxer de limits en el array passat per parametre
void load_limit_config(one_limit *limits){
    FILE * file;

    file = fopen(LIMIT_CONFIG_FILE,"r");
    if (!file){
    	perror("Error opening limit file");
    	exit(EXIT_FAILURE);
    }

    char line[256];
    int linenum=0;
    while(fgets(line, 256, file) != NULL)
    {
    	int cur, max;
    	char name[10];
    	if(line[0] != '#'){

				if(sscanf(line, "%s %d %d", name, &cur, &max) != 3)
				{
						perror("Error: bad syntax in limit config file");
						exit(EXIT_FAILURE);
				}
				int i = 0;
				for(i = 0; i < 11; i++){
    				if(strcmp(limits[i].name, name)==0){
    					limits[i].active = 1;
    					limits[i].l.rlim_cur = cur;
    					limits[i].l.rlim_max = max;
    					//printf("Resource %d: Name=%s soft=%d hard=%d\n", (int)limits[i].resource, limits[i].name, (int)limits[i].l.rlim_cur, (int)limits[i].l.rlim_max);
    				}
				}

				linenum++;
        }
    }

    fclose(file);
}

//Carrega la taula de crides a sistema en el array "syscalls"
void load_syscall_table(one_call *syscalls, int *syscalltable_size){
    FILE * file;

    file = fopen(SYSCALL_TABLE_CONFIG_FILE,"r");
    if (!file){
    	perror("Error opening syscall file");
    	exit(EXIT_FAILURE);
    }

    char line[256];
    int linenum=0;
    while(fgets(line, 256, file) != NULL)
    {
    	if(line[0] != '#'){
    			if(sscanf(line, "%s %d", syscalls[linenum].name, (int *)&syscalls[linenum].syscall) != 2)
    			{
    					perror("Error: bad syntax in syscalltable file");
    					exit(EXIT_FAILURE);
    			}
    			syscalls[linenum].maxcalls = MAXCALLS;
    			syscalls[linenum].numcalls = 0;
    			syscalls[linenum].in_call = 0;
    			linenum++;
    			*syscalltable_size += 1;
        }
    }

    fclose(file);
}

void load_syscall_limits(one_call *syscalls, int *syscalltable_size){
    FILE * file;

    file = fopen(SYSCALL_CONFIG_FILE,"r");
    if (!file){
    	perror("Error opening syscall limit configuration file");
    	exit(EXIT_FAILURE);
    }

    char line[256];
    int linenum=0;

    while(fgets(line, 256, file) != NULL)
    {
    	char name[10];
    	int max;
    	if(line[0] != '#'){
    			if(sscanf(line, "%s %d", name, &max) != 2)
    			{
    					perror("Error: bad syntax in syscalltable file");
    					exit(EXIT_FAILURE);
    			}

    			//Concatena __NR_ amb el nom trobat al fitxer de configuracio
    			char * s = malloc(snprintf(NULL, 0, "%s %s", "__NR_", name) + 1);
    			sprintf(s, "%s%s", "__NR_", name);

    			int i = 0;
    			int size = *syscalltable_size;
    			for(i=0; i < size; i++){
    				if(strcmp(syscalls[i].name, s)==0){
    					syscalls[i].maxcalls = max;
    				}
    			}
    			linenum++;
        }
    }

    fclose(file);
}


//Comprova si un fitxer existeix
int file_exists (char * fileName)
{
   struct stat buf;
   int i = stat ( fileName, &buf );
     /* File found */
     if ( i == 0 )
     {
       return 1;
     }
     return 0;

}


//Crea la taula de crides a sistema executant el script definit a SYSCALL_TABLE_GENERATOR
void generate_syscall_table(){
	pid_t pid = fork();
	char *args[] = { "/bin/bash", SYSCALL_TABLE_GENERATOR, NULL };
	switch(pid){
		case -1:
			perror("Error: Could not generate syscall table");
			exit(EXIT_FAILURE);
		case 0:
			//El proces fill executara l'script de generacio de la syscalltable

			execv("/bin/bash", args);
			//Mai s'hauria d'arribar aqui
			perror("Error: execve failed when generating syscall table");
			exit(EXIT_FAILURE);
	}

}

void set_resource_limits(one_limit *limits){
	int i;
	for(i = 0; i < 11; i++){
		if(limits[i].active == 1){
			int r = setrlimit(limits[i].resource, &limits[i].l);
			if (r) {
				perror("Error: setrlimit failed");
				exit(EXIT_FAILURE);
			}
			//printf("Setted resource = %d | name = %s\n", limits[i].resource, limits[i].name);
		}
	}

}


