--- rpl/src/instructions_o1.c 2012/02/23 15:38:29 1.46 +++ rpl/src/instructions_o1.c 2012/07/06 12:06:16 1.58 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.1.6 + RPL/2 (R) version 4.1.9 Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -919,6 +919,7 @@ instruction_open(struct_processus *s_eta logical1 erreur; logical1 existence; + logical1 negation; logical1 ouverture; logical1 presence_port; @@ -1030,7 +1031,7 @@ instruction_open(struct_processus *s_eta " { \"stty\" { \"stty parameters\" ... } } } OPEN\n"); printf(" { \"sockettype\" { \"name\" \"local name\" } } OPEN\n"); printf(" { \"sockettype\" \"socketdomain\" \"protection\" } OPEN\n"); - printf(" \"/semaphore\" OPEN\n"); + printf(" \"/semaphore\" OPEN\n\n"); printf(" File type : NEW/OLD/REPLACE/UNKNOWN/SCRATCH\n"); printf(" File access : SEQUENTIAL/DIRECT/KEYED\n"); @@ -1046,8 +1047,7 @@ instruction_open(struct_processus *s_eta printf(" IMAXBEL, OPOST, ONLCR, OCRNL, ONOCR, ONLRET,\n"); printf(" OFILL, HUPCL, CLOCAL, CRTSCTS, ISIG, ICANON,\n"); printf(" ECHO, ECHOE, ECHOK, ECHONL, NOFLSH, TOSTOP,\n"); - printf(" IEXTEN, VEOF, VEOL, VERASE, VINTR, VKILL,\n"); - printf(" VQUIT, VSTART, VSTOP, VSUSP\n"); + printf(" IEXTEN\n"); printf(" Address : { \"ADDRESS\" [ 127 0 0 1 ] }\n"); printf(" { \"HOST\" \"hostname\" }\n"); @@ -1069,7 +1069,7 @@ instruction_open(struct_processus *s_eta printf(" Port : { \"PORT\" port number }\n"); printf(" Protocol : { \"PROTOCOL\" \"protocol\" }\n\n"); - printf(" { { \"NAME\" \"filename\" } } OPEN\n"); + printf(" { { \"NAME\" \"filename\" } \"SEQUENTIAL\" } OPEN\n"); printf(" { \"SCRATCH\" } OPEN\n"); printf(" { { \"NAME\" \"filename\" } \"UNKNOWN\" \"FORMATTED\" " "\"DIRECT\" } OPEN\n"); @@ -1078,8 +1078,8 @@ instruction_open(struct_processus *s_eta printf(" { \"STREAM\" \"READWRITE\" } OPEN\n"); printf(" { \"FOREIGN\" \"DATAGRAM\" } OPEN\n"); printf(" { \"LOCAL\" { \"NAME\" \"socket.sock\" } } OPEN\n"); - printf(" { \"/dev/ttyS1\" { \"STTY\" { \"9600,8,N,1\" " - "\"NO ICANON\" \"IGNBRK\" } }\n"); + printf(" { { \"NAME\" \"/dev/ttyS1\" } { \"STTY\" { \"9600,8,N,1\" " + "\n { \"NO ICANON\" \"IGNBRK\" } } } OPEN\n"); return; } @@ -2272,7 +2272,7 @@ instruction_open(struct_processus *s_eta else if (strcmp(argument_majuscule, "STTY") == 0) { if ((*(*l_element_courant_sous_objet) - .donnee).type == LST) + .donnee).type == CHN) { if (type_arguments == ' ') { @@ -2289,8 +2289,7 @@ instruction_open(struct_processus *s_eta return; } - s_parametres_tty = - (*l_element_courant_sous_objet).donnee; + s_parametres_tty = (*l_element_courant).donnee; } } else @@ -2646,6 +2645,52 @@ instruction_open(struct_processus *s_eta free(argument_majuscule); } + else if (strcmp(argument_majuscule, "STTY") == 0) + { + if (type_arguments == ' ') + { + type_arguments = 'F'; + } + else if (type_arguments == 'S') + { + liberation(s_etat_processus, s_objet_argument); + free(argument_majuscule); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + free(argument_majuscule); + + l_element_courant_sous_objet = + (*l_element_courant_sous_objet).suivant; + + if ((*(*l_element_courant_sous_objet) + .donnee).type != CHN) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + l_element_courant_sous_objet = + (*l_element_courant_sous_objet).suivant; + + if ((*(*l_element_courant_sous_objet) + .donnee).type != LST) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + s_parametres_tty = (*l_element_courant).donnee; + } else { liberation(s_etat_processus, s_objet_argument); @@ -2686,6 +2731,14 @@ instruction_open(struct_processus *s_eta l_element_courant = (*l_element_courant).suivant; } + // Si aucun paramètre n'est discriminant, l'instruction ouvre + // par défaut un fichier. + + if (type_arguments == ' ') + { + type_arguments = 'F'; + } + if (type_arguments == 'F') { /* @@ -3537,7 +3590,11 @@ instruction_open(struct_processus *s_eta return; } - parametre_courant = (*s_parametres_tty).objet; + // Un test a déjà été fait pour vérifier que s_parametres_tty + // contient deux ou trois arguments. + + parametre_courant = ((*(struct_liste_chainee *) + (*s_parametres_tty).objet)).suivant; // Le premier paramètre concerne la vitesse du port. Il doit // toujours être présent. @@ -3600,14 +3657,32 @@ instruction_open(struct_processus *s_eta // Vitesse unsigned char *vitesses[] = - { "B0", "B50", "B75", "B110", "B134", "B150", - "B200", "B300", "B600", "B1200", "B1800", "B2400", - "B4800", "B9600", "B19200", "B38400", "B57600", - "B115200", "B230400", NULL }; + { "0", "50", "75", "110", "134", "150", + "200", "300", "600", "1200", "1800", "2400", + "4800", "9600", "19200", "38400", +#ifdef B57600 + "57600", +#endif +#ifdef B115200 + "115200", +#endif +#ifdef B230400 + "230400", +#endif + NULL }; int vitesses_constantes[] = { B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, - B57600, B115200, B230400, 0 }; +#ifdef B57600 + B57600, +#endif +#ifdef B115200 + B115200, +#endif +#ifdef B230400 + B230400, +#endif + 0 }; unsigned int vitesse_courante; vitesse_courante = 0; @@ -3620,8 +3695,15 @@ instruction_open(struct_processus *s_eta if (position[strlen(vitesses[vitesse_courante])] == d_code_espace) { +#ifdef CBAUD tc.c_cflag &= ~CBAUD; tc.c_cflag |= vitesses_constantes[vitesse_courante]; +#else // POSIX + cfsetispeed(&tc, + vitesses_constantes[vitesse_courante]); + cfsetospeed(&tc, + vitesses_constantes[vitesse_courante]); +#endif position += strlen(vitesses[vitesse_courante]); break; @@ -3757,6 +3839,8 @@ instruction_open(struct_processus *s_eta } } + position++; + if ((*position) != d_code_espace) { free(parametre_courant_majuscule); @@ -3809,6 +3893,8 @@ instruction_open(struct_processus *s_eta // S'il reste autre chose que des espaces, il y a un // problème de paramètres. + position++; + while((*position) != d_code_fin_chaine) { if ((*position) != d_code_espace) @@ -3828,11 +3914,191 @@ instruction_open(struct_processus *s_eta // Autres paramètres free(parametre_courant_majuscule); + parametre_courant = (*parametre_courant).suivant; + + if (parametre_courant != NULL) + { + parametre_courant = (*(*parametre_courant).donnee).objet; + } while(parametre_courant != NULL) { + if ((*(*parametre_courant).donnee).type != CHN) + { + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + if ((parametre_courant_majuscule = conversion_majuscule( + (*(*parametre_courant).donnee).objet)) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + position = parametre_courant_majuscule; + negation = d_faux; + + unsigned char *fonctions[] = + { "IGNBRK", "BRKINT", "IGNPAR", "PARMRK", + "INPCK", "ISTRIP", "INLCR", "IGNCR", "ICRNL", + "IXON", +#ifdef IXANY + "IXANY", +#endif + "IXOFF", "OPOST", + "ONLCR", "OCRNL", "ONOCR", "ONLRET", +#ifdef OFILL + "OFILL", +#endif + "HUPCL", "CLOCAL", +#ifdef CRTSCTS + "CRTSCTS", +#endif + "ISIG", "ICANON", "ECHO", "ECHOE", "ECHOK", + "ECHONL", "NOFLSH", "TOSTOP", "IEXTEN", NULL }; + int fonctions_constantes[] = + { /* c_iflag */ + 1, IGNBRK, 1, BRKINT, 1, IGNPAR, 1, PARMRK, + 1, INPCK, 1, ISTRIP, 1, INLCR, 1, IGNCR, 1, ICRNL, + 1, IXON, +#ifdef IXANY + 1, IXANY, +#endif + 1, IXOFF, + /* c_oflag */ + 2 , OPOST, 2, ONLCR, 2, OCRNL, 2, ONOCR, 2, ONLRET, +#ifdef OFILL + 2, OFILL, +#endif + 2, HUPCL, + /* c_cflag */ + 3, CLOCAL, +#ifdef CRTSCTS + 3, CRTSCTS, +#endif + /* c_lfkag */ + 4, ISIG, 4, ICANON, 4, ECHO, 4, ECHOE, 4, ECHOK, + 4, ECHONL, 4, NOFLSH, 4, TOSTOP, 4, IEXTEN }; + unsigned int fonction_courante; + + // On vient de trouver quelque chose à interpréter. + + if (strncmp(position, "NO ", 3) == 0) + { + position += 3; + negation = d_vrai; + } + + for(fonction_courante = 0; + fonctions[fonction_courante] != NULL; + fonction_courante++) + { + if (strcmp(fonctions[fonction_courante], position) + == 0) + { + if (negation == d_vrai) + { + switch(fonctions_constantes + [fonction_courante * 2]) + { + case 1: + { + tc.c_iflag &= ~fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 2: + { + tc.c_oflag &= ~fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 3: + { + tc.c_cflag &= ~fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 4: + { + tc.c_lflag &= ~fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + } + } + else + { + switch(fonctions_constantes + [fonction_courante * 2]) + { + case 1: + { + tc.c_iflag |= fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 2: + { + tc.c_oflag |= fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 3: + { + tc.c_cflag |= fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + + case 4: + { + tc.c_lflag |= fonctions_constantes + [(fonction_courante * 2) + 1]; + break; + } + } + } + + break; + } + } + + if (fonctions[fonction_courante] == NULL) + { + free(parametre_courant_majuscule); + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + free(parametre_courant_majuscule); parametre_courant = (*parametre_courant).suivant; } + + if (tcsetattr(fileno(descripteur), TCSANOW, &tc) != 0) + { + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_systeme = + d_ex_erreur_fichier; + return; + } } strcpy((*((struct_fichier *) (*s_objet_resultat).objet)).nom, nom); @@ -4469,18 +4735,22 @@ instruction_open(struct_processus *s_eta if (strcmp(protocole_socket, "IPV4") == 0) { protocole_socket[2] = d_code_fin_chaine; + protocole_numerique = 0; } - - if ((s_protocole = getprotobyname(protocole_socket)) == NULL) + else { - liberation(s_etat_processus, s_objet_argument); + if ((s_protocole = getprotobyname(protocole_socket)) + == NULL) + { + liberation(s_etat_processus, s_objet_argument); - (*s_etat_processus).erreur_execution = - d_ex_erreur_parametre_fichier; - return; - } + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } - protocole_numerique = (*s_protocole).p_proto; + protocole_numerique = (*s_protocole).p_proto; + } } if ((s_objet_resultat = allocation(s_etat_processus, SCK)) @@ -4502,6 +4772,7 @@ instruction_open(struct_processus *s_eta = protection; (*(*((struct_socket *) (*s_objet_resultat).objet)) .format).objet = NULL; + (*((struct_socket *) (*s_objet_resultat).objet)).adresse = NULL; switch(type_socket) { @@ -4765,6 +5036,9 @@ instruction_open(struct_processus *s_eta return; } + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(22 * sizeof(unsigned char))) == NULL) @@ -4869,6 +5143,9 @@ instruction_open(struct_processus *s_eta return; } + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(55 * sizeof(unsigned char))) == NULL) @@ -4900,6 +5177,15 @@ instruction_open(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + freeaddrinfo(resolution); + + (*s_etat_processus).erreur_execution = + d_ex_instruction_indisponible; + return; # endif } @@ -4914,6 +5200,9 @@ instruction_open(struct_processus *s_eta { // Hôte défini par une adresse if (strcmp(protocole, "IPV4") == 0) { // Accès en IPv4 + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(22 * sizeof(unsigned char))) == NULL) @@ -4989,6 +5278,9 @@ instruction_open(struct_processus *s_eta else { // Accès en IPv6 # ifdef IPV6 + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(55 * sizeof(unsigned char))) == NULL) @@ -5070,6 +5362,13 @@ instruction_open(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_instruction_indisponible; + return; # endif } } @@ -5303,6 +5602,9 @@ instruction_open(struct_processus *s_eta .socket_en_ecoute = 'N'; } + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(22 * sizeof(unsigned char))) == NULL) @@ -5409,6 +5711,9 @@ instruction_open(struct_processus *s_eta .socket_en_ecoute = 'N'; } + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(55 * sizeof(unsigned char))) == NULL) @@ -5440,6 +5745,15 @@ instruction_open(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + freeaddrinfo(resolution); + + (*s_etat_processus).erreur_execution = + d_ex_instruction_indisponible; + return; # endif } @@ -5456,6 +5770,9 @@ instruction_open(struct_processus *s_eta { // Accès en IPv4 if (type_adresse == '4') { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(22 * sizeof(unsigned char))) == NULL) @@ -5485,6 +5802,9 @@ instruction_open(struct_processus *s_eta } else { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc( sizeof(unsigned char))) == NULL) @@ -5552,6 +5872,9 @@ instruction_open(struct_processus *s_eta # ifdef IPV6 if (type_adresse == '6') { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc(55 * sizeof(unsigned char))) == NULL) @@ -5582,6 +5905,9 @@ instruction_open(struct_processus *s_eta } else { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc( sizeof(unsigned char))) == NULL) @@ -5652,10 +5978,20 @@ instruction_open(struct_processus *s_eta printf("+++Warning : IPv6 support " "unavailable\n"); } + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_instruction_indisponible; + return; # endif } else { // Socket UNIX + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc( sizeof(unsigned char))) == NULL)