--- rpl/src/instructions_o1.c 2010/08/06 15:26:48 1.17 +++ rpl/src/instructions_o1.c 2012/02/24 15:02:54 1.48 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.18 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.6 + Copyright (C) 1989-2012 Dr. BERTRAND Joël This file is part of RPL/2. @@ -897,6 +897,8 @@ instruction_open(struct_processus *s_eta * Format : * FORMATTED : fichier texte ; * UNFORMATTED : fichier binaire. + * FLOW : chaîne de caractères sans format (en tant qu'objet + * binaire comme "\x00avz\xFD") */ file *descripteur; @@ -917,6 +919,7 @@ instruction_open(struct_processus *s_eta logical1 erreur; logical1 existence; + logical1 negation; logical1 ouverture; logical1 presence_port; @@ -924,6 +927,7 @@ instruction_open(struct_processus *s_eta struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_sous_objet; + struct_liste_chainee *parametre_courant; struct flock lock; @@ -940,6 +944,9 @@ instruction_open(struct_processus *s_eta struct_objet *s_objet_argument; struct_objet *s_objet_resultat; + struct_objet *s_parametres_tty; + + struct termios tc; uint32_t adresse_ipv4; @@ -950,8 +957,10 @@ instruction_open(struct_processus *s_eta unsigned char *nom; unsigned char *nom_temporaire; unsigned char options[12]; + unsigned char *parametre_courant_majuscule; unsigned char *peripherique; unsigned char *pointeur; + unsigned char *position; unsigned char protection; unsigned char protocole[16 + 1]; unsigned char *protocole_socket; @@ -1017,6 +1026,9 @@ instruction_open(struct_processus *s_eta printf(" { \"filetype\" \"access\" \"format\" { \"name\" " "\"file name\" } \"protection\" } OPEN\n"); + printf(" { \"filetype\" \"access\" \"format\" { \"name\" " + "\"file name\" } \n" + " { \"stty\" { \"stty parameters\" ... } } } OPEN\n"); printf(" { \"sockettype\" { \"name\" \"local name\" } } OPEN\n"); printf(" { \"sockettype\" \"socketdomain\" \"protection\" } OPEN\n"); printf(" \"/semaphore\" OPEN\n"); @@ -1029,6 +1041,13 @@ instruction_open(struct_processus *s_eta printf(" Socket protocol : IPV4/IPV6/UNIX\n"); printf(" Format : FORMATTED/UNFORMATTED/FLOW\n"); printf(" Protection : READONLY/WRITEONLY/READWRITE\n\n"); + printf(" Stty parameters : can be prefixed by 'NO'\n"); + printf(" IGNBRK, BRKINT, IGNPAR, PARMRK, INPCK, ISTRIP\n"); + printf(" INLCR, IGNCR, ICRNL, IXON, IXANY, IXOFF,\n"); + 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\n"); printf(" Address : { \"ADDRESS\" [ 127 0 0 1 ] }\n"); printf(" { \"HOST\" \"hostname\" }\n"); @@ -1059,6 +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"); return; } @@ -1119,6 +1140,7 @@ instruction_open(struct_processus *s_eta timeout_emission = 0; timeout_reception = 0; drapeau = -1; + s_parametres_tty = NULL; for(i = 0; i < 12; options[i++] = 'N'); @@ -1190,6 +1212,34 @@ instruction_open(struct_processus *s_eta type_ouverture = 'R'; } + else if (strcmp(argument_majuscule, "OLD") == 0) + { + if (type_ouverture != ' ') + { + liberation(s_etat_processus, s_objet_argument); + free(argument_majuscule); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + + 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; + } + + type_ouverture = 'O'; + } else if (strcmp(argument_majuscule, "UNKNOWN") == 0) { if (type_ouverture != ' ') @@ -1942,6 +1992,15 @@ instruction_open(struct_processus *s_eta protocole_socket = (unsigned char *) (*(*l_element_courant_sous_objet) .donnee).objet; + + for(i = 0; i < strlen(protocole_socket); i++) + { + if ((protocole_socket[i] >= 'a') && + (protocole_socket[i] <= 'z')) + { + protocole_socket[i] -= 'a' - 'A'; + } + } } else { @@ -2210,6 +2269,30 @@ instruction_open(struct_processus *s_eta } } } + else if (strcmp(argument_majuscule, "STTY") == 0) + { + if ((*(*l_element_courant_sous_objet) + .donnee).type == LST) + { + 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; + } + + s_parametres_tty = + (*l_element_courant_sous_objet).donnee; + } + } else { liberation(s_etat_processus, s_objet_argument); @@ -2782,10 +2865,17 @@ instruction_open(struct_processus *s_eta return; } + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -2888,10 +2978,17 @@ instruction_open(struct_processus *s_eta } else { + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -3027,10 +3124,17 @@ instruction_open(struct_processus *s_eta } else { + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -3138,10 +3242,17 @@ instruction_open(struct_processus *s_eta } else { + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -3232,10 +3343,17 @@ instruction_open(struct_processus *s_eta } else { + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -3310,10 +3428,17 @@ instruction_open(struct_processus *s_eta return; } + sqlite = NULL; + if (sqlite3_open_v2(nom, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { + if (sqlite != NULL) + { + sqlite3_close(sqlite); + } + free(nom); liberation(s_etat_processus, s_objet_argument); @@ -3398,6 +3523,476 @@ instruction_open(struct_processus *s_eta return; } + if (s_parametres_tty != NULL) + { + // Affectation des paramètres du port série. + + if (tcgetattr(fileno(descripteur), &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; + } + + parametre_courant = (*s_parametres_tty).objet; + + // Le premier paramètre concerne la vitesse du port. Il doit + // toujours être présent. + + if (parametre_courant == NULL) + { + 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).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) + { + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + position = parametre_courant_majuscule; + + while((*position) != d_code_fin_chaine) + { + if ((*position) == ',') + { + (*position) = ' '; + } + + position++; + } + + position = parametre_courant_majuscule; + + while((*position) != d_code_fin_chaine) + { + if (isalnum((*position)) != 0) + { + break; + } + + position++; + } + + // 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, + B1200, B1800, B2400, B4800, B9600, B19200, B38400, + B57600, B115200, B230400, 0 }; + unsigned int vitesse_courante; + + vitesse_courante = 0; + + while(vitesses[vitesse_courante] != NULL) + { + if (strncmp(position, vitesses[vitesse_courante], + strlen(vitesses[vitesse_courante])) == 0) + { + if (position[strlen(vitesses[vitesse_courante])] == + d_code_espace) + { + tc.c_cflag &= ~CBAUD; + tc.c_cflag |= vitesses_constantes[vitesse_courante]; + position += strlen(vitesses[vitesse_courante]); + + break; + } + } + + vitesse_courante++; + } + + if (vitesses[vitesse_courante] == NULL) + { + // La vitesse indiquée n'est pas une vitesse autorisée. + + 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; + } + + // Nombre de bits par caractère. + + while((*position) != d_code_fin_chaine) + { + if (isalnum((*position)) != 0) + { + break; + } + + position++; + } + + switch((*position)) + { + case '5': + { + tc.c_cflag &= ~CSIZE; + tc.c_cflag |= CS5; + break; + } + + case '6': + { + tc.c_cflag &= ~CSIZE; + tc.c_cflag |= CS6; + break; + } + + case '7': + { + tc.c_cflag &= ~CSIZE; + tc.c_cflag |= CS7; + break; + } + + case '8': + { + tc.c_cflag &= ~CSIZE; + tc.c_cflag |= CS8; + break; + } + + default: + { + 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; + } + } + + position++; + + if ((*position) != d_code_espace) + { + 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; + } + + // Parité + + while((*position) != d_code_fin_chaine) + { + if (isalnum((*position)) != 0) + { + break; + } + + position++; + } + + switch((*position)) + { + case 'N': + { + tc.c_cflag &= ~PARENB; + break; + } + + case 'O': + { + tc.c_cflag |= PARENB; + tc.c_cflag |= PARODD; + break; + } + + case 'E': + { + tc.c_cflag |= PARENB; + tc.c_cflag &= ~PARODD; + break; + } + + default: + { + 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; + } + } + + if ((*position) != d_code_espace) + { + 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; + } + + // Bits de stop + + while((*position) != d_code_fin_chaine) + { + if (isalnum((*position)) != 0) + { + break; + } + + position++; + } + + switch((*position)) + { + case '1': + { + tc.c_cflag &= ~CSTOPB; + break; + } + + case '2': + { + tc.c_cflag |= CSTOPB; + break; + } + + default: + { + 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; + } + } + + // S'il reste autre chose que des espaces, il y a un + // problème de paramètres. + + while((*position) != d_code_fin_chaine) + { + if ((*position) != d_code_espace) + { + 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; + } + + position++; + } + + // Autres paramètres + + free(parametre_courant_majuscule); + parametre_courant = (*parametre_courant).suivant; + + 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", "IXANY", "IXOFF", "OPOST", + "ONLCR", "OCRNL", "ONOCR", "ONLRET", + "OFILL", "HUPCL", "CLOCAL", "CRTSCTS", + "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, 1, IXANY, 1, IXOFF, + /* c_oflag */ + 2 , OPOST, 2, ONLCR, 2, OCRNL, 2, ONOCR, 2, ONLRET, + 2, OFILL, 2, HUPCL, + /* c_cflag */ + 3, CLOCAL, 3, CRTSCTS, + /* c_lfkag */ + 4, ISIG, 4, ICANON, 4, ECHO, 4, ECHOE, 4, ECHOK, + 4, ECHONL, 4, NOFLSH, 4, TOSTOP, 4, IEXTEN }; + unsigned int fonction_courante; + + if (isalnum((*position)) != 0) + { + // 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); liberation(s_etat_processus, s_objet_argument); @@ -3976,6 +4571,28 @@ instruction_open(struct_processus *s_eta return; } + if ((type_adresse == ' ') && (type_domaine == 'L')) + { + if (strcmp(protocole, "IPV4") == 0) + { + for(i = 0; i < 4; adresse[i++] = 0); + type_adresse = '4'; + } + else if (strcmp(protocole, "IPV6") == 0) + { + for(i = 0; i < 16; adresse[i++] = 0); + type_adresse = '6'; + } + else + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return; + } + } + if (((strcmp(protocole, "IPV4") == 0) && (type_adresse == '6')) || ((strcmp(protocole, "IPV6") == 0) && (type_adresse == '4'))) { @@ -4007,16 +4624,7 @@ instruction_open(struct_processus *s_eta } else { - for(i = 0; i < strlen(protocole_socket); i++) - { - if ((protocole_socket[i] >= 'A') && - (protocole_socket[i] <= 'Z')) - { - protocole_socket[i] += 'a' - 'A'; - } - } - - if (strcmp(protocole_socket, "ipv4") == 0) + if (strcmp(protocole_socket, "IPV4") == 0) { protocole_socket[2] = d_code_fin_chaine; } @@ -4185,8 +4793,8 @@ instruction_open(struct_processus *s_eta pointeur++; } - strncpy(socket_unix.sun_path, pointeur, 108); - socket_unix.sun_path[108 - 1] = d_code_fin_chaine; + strncpy(socket_unix.sun_path, pointeur, UNIX_PATH_MAX); + socket_unix.sun_path[UNIX_PATH_MAX - 1] = d_code_fin_chaine; if (options_socket() == d_erreur) { @@ -4440,6 +5048,16 @@ instruction_open(struct_processus *s_eta .sin6_addr.s6_addr[i]); } # else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } # endif } @@ -4600,6 +5218,16 @@ instruction_open(struct_processus *s_eta return; } # else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } # endif } } @@ -4704,8 +5332,8 @@ instruction_open(struct_processus *s_eta socket_unix.sun_family = AF_UNIX; strncpy(socket_unix.sun_path, (*((struct_socket *) - (*s_objet_resultat).objet)).adresse, 108); - socket_unix.sun_path[108 - 1] = d_code_fin_chaine; + (*s_objet_resultat).objet)).adresse, UNIX_PATH_MAX); + socket_unix.sun_path[UNIX_PATH_MAX - 1] = d_code_fin_chaine; if ((type_socket == 'S') || (type_socket == 'Q')) { @@ -4960,6 +5588,16 @@ instruction_open(struct_processus *s_eta .sin6_addr.s6_addr[i]); } # else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } # endif } @@ -5162,6 +5800,16 @@ instruction_open(struct_processus *s_eta .socket_en_ecoute = 'N'; } # else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + printf("+++Warning : IPv6 support " + "unavailable\n"); + } # endif } else