--- rpl/src/instructions_o1.c 2012/02/23 15:38:29 1.46 +++ rpl/src/instructions_o1.c 2014/07/17 08:07:23 1.77 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.6 - Copyright (C) 1989-2012 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.19 + Copyright (C) 1989-2014 Dr. BERTRAND Joël This file is part of RPL/2. @@ -210,7 +210,7 @@ instruction_or(struct_processus *s_etat_ struct_objet *s_objet_argument_2; struct_objet *s_objet_resultat; - unsigned long nombre_elements; + integer8 nombre_elements; (*s_etat_processus).erreur_execution = d_ex; @@ -907,6 +907,7 @@ instruction_open(struct_processus *s_eta int buffer_reception; int drapeau; int priorite; + int prochain_descripteur; int protocole_numerique; int timeout_emission; int timeout_reception; @@ -919,6 +920,7 @@ instruction_open(struct_processus *s_eta logical1 erreur; logical1 existence; + logical1 negation; logical1 ouverture; logical1 presence_port; @@ -972,7 +974,6 @@ instruction_open(struct_processus *s_eta unsigned long i; unsigned long nombre_elements; - unsigned long prochain_descripteur; unsigned long unite; # define d_BIND_TO_DEVICE 0 @@ -1027,10 +1028,11 @@ instruction_open(struct_processus *s_eta "\"file name\" } \"protection\" } OPEN\n"); printf(" { \"filetype\" \"access\" \"format\" { \"name\" " "\"file name\" } \n" - " { \"stty\" { \"stty parameters\" ... } } } OPEN\n"); + " { \"stty\" \"speed,bits,parity,stop\"\n" + " { \"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 +1048,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 +1070,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 +1079,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; } @@ -1998,7 +1999,9 @@ instruction_open(struct_processus *s_eta if ((protocole_socket[i] >= 'a') && (protocole_socket[i] <= 'z')) { - protocole_socket[i] -= 'a' - 'A'; + protocole_socket[i] = (unsigned char) + (protocole_socket[i] + - ('a' - 'A')); } } } @@ -2141,7 +2144,6 @@ instruction_open(struct_processus *s_eta { type_arguments = 'S'; } - else if (type_arguments == 'F') { liberation(s_etat_processus, s_objet_argument); @@ -2272,7 +2274,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 +2291,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 +2647,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 +2733,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 +3592,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 +3659,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 }; - int vitesses_constantes[] = - { B0, B50, B75, B110, B134, B150, B200, B300, B600, + { "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 }; + tcflag_t vitesses_constantes[] = + { 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 +3697,15 @@ instruction_open(struct_processus *s_eta if (position[strlen(vitesses[vitesse_courante])] == d_code_espace) { - tc.c_cflag &= ~CBAUD; +#ifdef CBAUD + tc.c_cflag &= ~((tcflag_t) 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; @@ -3660,28 +3744,28 @@ instruction_open(struct_processus *s_eta { case '5': { - tc.c_cflag &= ~CSIZE; + tc.c_cflag &= ~((tcflag_t) CSIZE); tc.c_cflag |= CS5; break; } case '6': { - tc.c_cflag &= ~CSIZE; + tc.c_cflag &= ~((tcflag_t) CSIZE); tc.c_cflag |= CS6; break; } case '7': { - tc.c_cflag &= ~CSIZE; + tc.c_cflag &= ~((tcflag_t) CSIZE); tc.c_cflag |= CS7; break; } case '8': { - tc.c_cflag &= ~CSIZE; + tc.c_cflag &= ~((tcflag_t) CSIZE); tc.c_cflag |= CS8; break; } @@ -3727,7 +3811,7 @@ instruction_open(struct_processus *s_eta { case 'N': { - tc.c_cflag &= ~PARENB; + tc.c_cflag &= ~((tcflag_t) PARENB); break; } @@ -3741,7 +3825,7 @@ instruction_open(struct_processus *s_eta case 'E': { tc.c_cflag |= PARENB; - tc.c_cflag &= ~PARODD; + tc.c_cflag &= ~((tcflag_t) PARODD); break; } @@ -3757,6 +3841,8 @@ instruction_open(struct_processus *s_eta } } + position++; + if ((*position) != d_code_espace) { free(parametre_courant_majuscule); @@ -3784,7 +3870,7 @@ instruction_open(struct_processus *s_eta { case '1': { - tc.c_cflag &= ~CSTOPB; + tc.c_cflag &= ~((tcflag_t) CSTOPB); break; } @@ -3809,6 +3895,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 +3916,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 }; + tcflag_t 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); @@ -4041,7 +4309,7 @@ instruction_open(struct_processus *s_eta return; } - prochain_descripteur = i; + prochain_descripteur = (int) i; /* * Ajout d'un élément à la fin de la liste chaînée @@ -4131,7 +4399,8 @@ instruction_open(struct_processus *s_eta # ifdef SO_BINDTODEVICE if (setsockopt((*((struct_socket *) (*s_objet_resultat) .objet)).socket, SOL_SOCKET, SO_BINDTODEVICE, - peripherique, strlen(peripherique)) != 0) + peripherique, (socklen_t) strlen(peripherique)) + != 0) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -4425,7 +4694,7 @@ instruction_open(struct_processus *s_eta for(i = 0; i < 16; adresse[i++] = 0); type_adresse = '6'; } - else + else if (strcmp(protocole, "UNIX") != 0) { liberation(s_etat_processus, s_objet_argument); @@ -4469,18 +4738,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 +4775,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 +5039,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 +5146,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 +5180,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 +5203,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) @@ -4962,7 +5254,8 @@ instruction_open(struct_processus *s_eta adresse_ipv4 = 0; for(i = 0; i < 4; adresse_ipv4 = - (256 * adresse_ipv4) + adresse[i++]); + (256 * adresse_ipv4) + + ((unsigned char) adresse[i++])); socket_ipv4.sin_addr.s_addr = htonl(adresse_ipv4); @@ -4989,6 +5282,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 +5366,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 +5606,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 +5715,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 +5749,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 +5774,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 +5806,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) @@ -5520,7 +5844,8 @@ instruction_open(struct_processus *s_eta adresse_ipv4 = 0; for(i = 0; i < 4; adresse_ipv4 = - (256 * adresse_ipv4) + adresse[i++]); + (256 * adresse_ipv4) + + ((unsigned char) adresse[i++])); socket_ipv4.sin_addr.s_addr = htonl(adresse_ipv4); @@ -5552,6 +5877,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 +5910,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 +5983,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)