--- rpl/src/rpl.c 2011/09/20 14:36:30 1.91 +++ rpl/src/rpl.c 2011/11/30 17:21:07 1.103 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.1.3 + RPL/2 (R) version 4.1.5 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. @@ -31,11 +31,19 @@ */ int -rplinit(int argc, char *argv[], unsigned char ***resultats, char *rpl_home) +rplinit(int argc, char *argv[], char *envp[], + unsigned char ***resultats, char *rpl_home) { # include "copyright-conv.h" # include "licence-conv.h" +# ifdef HAVE_STACK_OVERFLOW_RECOVERY + char pile_signaux[SIGSTKSZ]; +# endif + +# define RPL_PATH_MAX 1024 + char repertoire_initial[RPL_PATH_MAX]; + file *f_source; int erreur_historique; @@ -100,6 +108,7 @@ rplinit(int argc, char *argv[], unsigned errno = 0; s_queue_signaux = NULL; + routine_recursive = 0; pid_processus_pere = getpid(); # ifdef DEBUG_MEMOIRE @@ -112,7 +121,7 @@ rplinit(int argc, char *argv[], unsigned # ifndef SEMAPHORES_NOMMES sem_init(&semaphore_gestionnaires_signaux, 0, 0); # else - semaphore_gestionnaires_signaux = sem_init2(0, getpid()); + semaphore_gestionnaires_signaux = sem_init2(0, getpid(), SEM_SIGNAUX); if (semaphore_gestionnaires_signaux == SEM_FAILED) { @@ -171,13 +180,34 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).langue = 'E'; } + if (getcwd(repertoire_initial, RPL_PATH_MAX) == NULL) + { + if ((langue = getenv("LANG")) != NULL) + { + if (strncmp(langue, "fr", 2) == 0) + { + uprintf("+++Système : Mémoire insuffisante\n"); + } + else + { + uprintf("+++System : Not enough memory\n"); + } + } + else + { + uprintf("+++System : Not enough memory\n"); + } + + return(EXIT_FAILURE); + } + initialisation_contexte_cas(s_etat_processus); (*s_etat_processus).exception = d_ep; (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex; - (*s_etat_processus).compteur_violation_d_acces = 0; + (*s_etat_processus).requete_redemarrage = d_faux; (*s_etat_processus).rpl_home = rpl_home; pthread_mutexattr_init(&attributs_mutex); @@ -195,7 +225,7 @@ rplinit(int argc, char *argv[], unsigned sem_init(&((*s_etat_processus).semaphore_fork), 0, 0); # else if (((*s_etat_processus).semaphore_fork = sem_init3(0, getpid(), - pthread_self())) == SEM_FAILED) + pthread_self(), SEM_FORK)) == SEM_FAILED) { if ((*s_etat_processus).langue == 'F') { @@ -314,50 +344,40 @@ rplinit(int argc, char *argv[], unsigned home = ""; } - // Initialisation d'une pile de signal pour récupérer les - // débordement de pile - -# if !defined(Cygwin) && !defined(OpenBSD) - if (((*s_etat_processus).pile_signal.ss_sp = - malloc((*s_etat_processus).pile_signal.ss_size = - SIGSTKSZ)) == NULL) - { - erreur = d_es_allocation_memoire; - - if ((*s_etat_processus).langue == 'F') +# ifdef HAVE_STACK_OVERFLOW_RECOVERY + if (stackoverflow_install_handler(interruption_depassement_pile, + pile_signaux, sizeof(pile_signaux)) != 0) { - printf("+++Système : Mémoire insuffisante\n"); - } - else - { - printf("+++System : Not enough memory\n"); - } + erreur = d_es_signal; - return(EXIT_FAILURE); - } - - (*s_etat_processus).pile_signal.ss_flags = 0; - - if (sigaltstack(&((*s_etat_processus).pile_signal), NULL) != 0) - { - erreur = d_es_signal; + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation de la pile alternative " + "impossible\n"); + } + else + { + printf("+++System : Initialization of alternate " + "stack failed\n"); + } + return(EXIT_FAILURE); + } +# else if ((*s_etat_processus).langue == 'F') { - printf("+++Système : Initialisation de la pile spécifique de signal" - " impossible\n"); + printf("+++Attention : Le système ne supporte pas de pile " + "alternative\n"); } else { - printf("+++System : Initialization of signal stack failed\n"); + printf("+++Warning : Operating system does not support alternate " + "stack\n"); } - - return(EXIT_FAILURE); - } # endif action.sa_handler = interruption1; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGINT, &action, NULL) != 0) { @@ -434,7 +454,7 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption2; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGTSTP, &action, NULL) != 0) { @@ -472,7 +492,7 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption5; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGPIPE, &action, NULL) != 0) { @@ -512,9 +532,9 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption1; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; - if (sigaction(SIGALRM, &action, NULL) != 0) + if (sigaction(SIGUSR1, &action, NULL) != 0) { erreur = d_es_signal; @@ -532,9 +552,9 @@ rplinit(int argc, char *argv[], unsigned } signal_test = SIGTEST; - kill(getpid(), SIGALRM); + kill(getpid(), SIGUSR1); - if (signal_test != SIGALRM) + if (signal_test != SIGUSR1) { erreur = d_es_signal; @@ -1453,10 +1473,36 @@ rplinit(int argc, char *argv[], unsigned } } + /* + * Dans le cas où le programme est appelé avec l'option -d, + * on ne récupère par les signaux de violation d'accès. On + * tente simplement la récupération des dépassements de pile. + */ + if (debug == d_faux) { + +# ifdef HAVE_SIGSEGV_RECOVERY + if (sigsegv_install_handler(interruption_violation_access) != 0) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation de la pile alternative " + "impossible\n"); + } + else + { + printf("+++System : Initialization of alternate " + "stack failed\n"); + } + + return(EXIT_FAILURE); + } +# else action.sa_handler = interruption3; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGSEGV, &action, NULL) != 0) { @@ -1474,6 +1520,28 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGSEGV); + + if (signal_test != SIGSEGV) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals " + "failed\n"); + } + + return(EXIT_FAILURE); + } +# endif + if (sigaction(SIGBUS, &action, NULL) != 0) { if ((*s_etat_processus).langue == 'F') @@ -1489,12 +1557,34 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + + signal_test = SIGTEST; + kill(getpid(), SIGBUS); + + if (signal_test != SIGBUS) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals " + "failed\n"); + } + + return(EXIT_FAILURE); + } + } if (option_n == d_vrai) { action.sa_handler = interruption4; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGHUP, &action, NULL) != 0) { @@ -2693,16 +2783,6 @@ rplinit(int argc, char *argv[], unsigned l_element_courant = (*s_etat_processus).liste_mutexes; while(l_element_courant != NULL) { - pthread_mutex_trylock(&((*((struct_mutex *) - (*(*((struct_liste_chainee *) - l_element_courant)).donnee).objet)).mutex)); - pthread_mutex_unlock(&((*((struct_mutex *) - (*(*((struct_liste_chainee *) - l_element_courant)).donnee).objet)).mutex)); - pthread_mutex_destroy(&((*((struct_mutex *) - (*(*((struct_liste_chainee *) - l_element_courant)).donnee).objet)).mutex)); - liberation(s_etat_processus, (*((struct_liste_chainee *) l_element_courant)).donnee); @@ -2914,7 +2994,7 @@ rplinit(int argc, char *argv[], unsigned .thread).nombre_objets_dans_pipe--; action.sa_handler = SIG_IGN; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGPIPE, &action, ®istre) != 0) @@ -3487,11 +3567,12 @@ rplinit(int argc, char *argv[], unsigned pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation)); # ifndef SEMAPHORES_NOMMES - sem_post(&((*s_etat_processus).semaphore_fork); - sem_destroy(&((*s_etat_processus).semaphore_fork); + sem_post(&((*s_etat_processus).semaphore_fork)); + sem_destroy(&((*s_etat_processus).semaphore_fork)); # else sem_post((*s_etat_processus).semaphore_fork); - sem_destroy3((*s_etat_processus).semaphore_fork, getpid(), pthread_self()); + sem_destroy3((*s_etat_processus).semaphore_fork, getpid(), pthread_self(), + SEM_FORK); # endif free((*s_etat_processus).localisation); @@ -3504,13 +3585,24 @@ rplinit(int argc, char *argv[], unsigned sem_destroy(&semaphore_gestionnaires_signaux); # else sem_post(semaphore_gestionnaires_signaux); - sem_destroy2(semaphore_gestionnaires_signaux, getpid()); + sem_destroy2(semaphore_gestionnaires_signaux, getpid(), SEM_SIGNAUX); # endif destruction_queue_signaux(s_etat_processus); liberation_contexte_cas(s_etat_processus); free((*s_etat_processus).chemin_fichiers_temporaires); + + if ((*s_etat_processus).requete_redemarrage == d_vrai) + { + chdir(repertoire_initial); + execve(argv[0], (*(argv + 1)), envp); + erreur = d_erreur; + } + + // Libération de la copie des arguments + // A FAIRE + free(s_etat_processus); # ifdef DEBUG_MEMOIRE @@ -3518,6 +3610,17 @@ rplinit(int argc, char *argv[], unsigned analyse_post_mortem(); # endif +# ifdef HAVE_STACK_OVERFLOW_RECOVERY + stackoverflow_deinstall_handler(); +# endif + +# ifdef HAVE_SIGSEGV_RECOVERY + if (debug == d_faux) + { + sigsegv_deinstall_handler(); + } +# endif + return((erreur == d_absence_erreur) ? EXIT_SUCCESS : EXIT_FAILURE); } @@ -3573,4 +3676,72 @@ informations(struct_processus *s_etat_pr return; } + +logical1 +controle_integrite(struct_processus *s_etat_processus, + unsigned char *executable_candidat, unsigned char *executable) +{ + unsigned char *md5; + unsigned char *sha1; + + if (strcmp(executable, "rplpp") == 0) + { + md5 = rplpp_md5; + sha1 = rplpp_sha1; + } + else if (strcmp(executable, "rplfile") == 0) + { + md5 = rplfile_md5; + sha1 = rplfile_sha1; + } + else if (strcmp(executable, "rpliconv") == 0) + { + md5 = rpliconv_md5; + sha1 = rpliconv_sha1; + } + else if (strcmp(executable, "rplawk") == 0) + { + md5 = rplawk_md5; + sha1 = rplawk_sha1; + } + else if (strcmp(executable, "rplconvert") == 0) + { + md5 = rplconvert_md5; + sha1 = rplconvert_sha1; + } + else + { + return(d_faux); + } + + if (controle(s_etat_processus, executable_candidat, "md5", md5) != d_vrai) + { + return(d_faux); + } + + if (controle(s_etat_processus, executable_candidat, "sha1", sha1) != d_vrai) + { + return(d_faux); + } + + return(d_vrai); +} + + +unsigned char * +date_compilation() +{ + unsigned char *date; + + if ((date = malloc((strlen(d_date_en_rpl) + 1) * sizeof(unsigned char))) + == NULL) + { + return(NULL); + } + + strcpy(date, d_date_en_rpl); + + return(date); +} + // vim: ts=4