--- rpl/src/instructions_o1.c 2010/03/04 10:17:52 1.4 +++ rpl/src/instructions_o1.c 2023/08/07 17:42:56 1.107 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.12 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.35 + Copyright (C) 1989-2023 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -114,35 +114,35 @@ instruction_over(struct_processus *s_eta " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s,\n" - " %s, %s\n", + " %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SQL, d_SLB, d_PRC, d_MTX); + d_SQL, d_SLB, d_PRC, d_MTX, d_REC); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s,\n" - " %s, %s\n", + " %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SQL, d_SLB, d_PRC, d_MTX); + d_SQL, d_SLB, d_PRC, d_MTX, d_REC); printf("-> 3: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s,\n" - " %s, %s\n", + " %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SQL, d_SLB, d_PRC, d_MTX); + d_SQL, d_SLB, d_PRC, d_MTX, d_REC); printf(" ...\n"); printf(" 1: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s,\n" - " %s, %s\n", + " %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_TAB, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN, d_FCH, d_SCK, - d_SQL, d_SLB, d_PRC, d_MTX); + d_SQL, d_SLB, d_PRC, d_MTX, d_REC); return; } @@ -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; @@ -869,6 +869,237 @@ instruction_or(struct_processus *s_etat_ ================================================================================ */ + +static inline logical1 +options_socket(struct_processus *s_etat_processus, + struct_objet *s_objet_resultat, unsigned char *options, + unsigned char *peripherique, int *priorite, + int *buffer_emission, int *buffer_reception, + int *timeout_emission, int *timeout_reception) +{ + int drapeau; + + /* + * Options des sockets + */ + + drapeau = -1; + +# define WARNING(message) { \ + if ((*s_etat_processus).langue != 'F') \ + printf("+++Warning : %s unavailable on host system\n", message); \ + else \ + printf("+++Attention : %s non disponible sur le système hôte\n", \ + message); } while(0) + + if (options[d_BIND_TO_DEVICE] == 'Y') + { +# ifdef SO_BINDTODEVICE + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)) + .socket, SOL_SOCKET, SO_BINDTODEVICE, peripherique, + (socklen_t) strlen(peripherique)) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_BIND_TO_DEVICE; +# else + WARNING("BIND TO DEVICE"); +# endif + } + + if (options[d_BROADCAST] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_BROADCAST, &drapeau, sizeof(drapeau)) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_BROADCAST; + } + + if (options[d_DONT_ROUTE] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_DONTROUTE, &drapeau, sizeof(drapeau)) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_DONT_ROUTE; + } + + if (options[d_KEEP_ALIVE] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_KEEPALIVE, &drapeau, sizeof(drapeau)) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + } + + if (options[d_PRIORITY] == 'Y') + { +# ifdef SO_PRIORITY + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)) + .socket, SOL_SOCKET, SO_PRIORITY, priorite, + sizeof((*priorite))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_PRIORITY; + (*((struct_socket *) (*s_objet_resultat).objet)).priorite = + (*priorite); +# else + WARNING("PRIORITY"); +# endif + } + + if (options[d_RECEIVE_BUFFER] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_RCVBUF, buffer_reception, + sizeof((*buffer_reception))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_RECEIVE_BUFFER; + (*((struct_socket *) (*s_objet_resultat).objet)).buffer_reception = + (*buffer_reception); + } + + if (options[d_FORCE_RECEIVE_BUFFER] == 'Y') + { +# ifdef SO_RCVBUFFORCE + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)) + .socket, SOL_SOCKET, SO_RCVBUFFORCE, + buffer_reception, sizeof((*buffer_reception))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_FORCE_RECEIVE_BUFFER; + (*((struct_socket *) (*s_objet_resultat).objet)).buffer_reception = + (*buffer_reception); +# else + WARNING("FORCE_RECEIVE_BUFFER"); +# endif + } + + if (options[d_SEND_BUFFER] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_SNDBUF, buffer_emission, + sizeof((*buffer_emission))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_SEND_BUFFER; + (*((struct_socket *) (*s_objet_resultat).objet)).buffer_emission = + (*buffer_emission); + } + + if (options[d_FORCE_SEND_BUFFER] == 'Y') + { +# ifdef SO_SNDBUFFORCE + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)) + .socket, SOL_SOCKET, SO_SNDBUFFORCE, buffer_emission, + sizeof((*buffer_emission))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_FORCE_SEND_BUFFER; + (*((struct_socket *) (*s_objet_resultat).objet)).buffer_emission = + (*buffer_emission); +# else + WARNING("FORCE_SEND_BUFFER"); +# endif + } + + if (options[d_RECEIVING_TIMEOUT] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_RCVTIMEO, + timeout_reception, sizeof((*timeout_reception))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_RECEIVING_TIMEOUT; + (*((struct_socket *) (*s_objet_resultat).objet)).timeout_reception = + (*timeout_reception); + } + + if (options[d_SENDING_TIMEOUT] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_SNDTIMEO, + timeout_emission, sizeof((*timeout_emission))) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_SENDING_TIMEOUT; + (*((struct_socket *) (*s_objet_resultat).objet)).timeout_emission = + (*timeout_emission); + } + + if (options[d_REUSE_ADDRESS] == 'Y') + { + if (setsockopt((*((struct_socket *) (*s_objet_resultat).objet)).socket, + SOL_SOCKET, SO_REUSEADDR, &drapeau, sizeof(drapeau)) != 0) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_parametre_fichier; + return(d_erreur); + } + + (*((struct_socket *) (*s_objet_resultat).objet)).options |= + ((integer8) 1) << d_REUSE_ADDRESS; + } + + return(d_absence_erreur); +# undef WARNING +} + + void instruction_open(struct_processus *s_etat_processus) { @@ -897,14 +1128,16 @@ 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; int buffer_emission; int buffer_reception; - int drapeau; int priorite; + int prochain_descripteur; int protocole_numerique; int timeout_emission; int timeout_reception; @@ -915,14 +1148,17 @@ instruction_open(struct_processus *s_eta integer8 port; integer8 position_clef; - logical1 autorisation_liberation_nom; logical1 erreur; logical1 existence; + logical1 negation; logical1 ouverture; logical1 presence_port; + sqlite3 *sqlite; + struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_sous_objet; + struct_liste_chainee *parametre_courant; struct flock lock; @@ -933,10 +1169,15 @@ instruction_open(struct_processus *s_eta struct sockaddr_un socket_unix; struct sockaddr_in socket_ipv4; +# ifdef IPV6 struct sockaddr_in6 socket_ipv6; +# endif struct_objet *s_objet_argument; struct_objet *s_objet_resultat; + struct_objet *s_parametres_tty; + + struct termios tc; uint32_t adresse_ipv4; @@ -947,8 +1188,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; @@ -961,22 +1204,8 @@ 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 -# define d_BROADCAST 1 -# define d_DONT_ROUTE 2 -# define d_KEEP_ALIVE 3 -# define d_PRIORITY 4 -# define d_RECEIVE_BUFFER 5 -# define d_FORCE_RECEIVE_BUFFER 6 -# define d_SEND_BUFFER 7 -# define d_FORCE_SEND_BUFFER 8 -# define d_RECEIVING_TIMEOUT 9 -# define d_SENDING_TIMEOUT 10 -# define d_REUSE_ADDRESS 11 - /* * Argument : { "ouverture" "accès" "format" [ { "nom" } 'protection' ] } */ @@ -1014,8 +1243,13 @@ 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\" \"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\n"); printf(" File type : NEW/OLD/REPLACE/UNKNOWN/SCRATCH\n"); printf(" File access : SEQUENTIAL/DIRECT/KEYED\n"); @@ -1025,6 +1259,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, RAW\n"); printf(" Address : { \"ADDRESS\" [ 127 0 0 1 ] }\n"); printf(" { \"HOST\" \"hostname\" }\n"); @@ -1046,7 +1287,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"); @@ -1055,6 +1296,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(" { { \"NAME\" \"/dev/ttyS1\" } { \"STTY\" \"9600,8,N,1\" " + "\n { \"NO ICANON\" \"IGNBRK\" } } } OPEN\n"); return; } @@ -1114,7 +1357,7 @@ instruction_open(struct_processus *s_eta buffer_reception = 0; timeout_emission = 0; timeout_reception = 0; - drapeau = -1; + s_parametres_tty = NULL; for(i = 0; i < 12; options[i++] = 'N'); @@ -1122,8 +1365,9 @@ instruction_open(struct_processus *s_eta { if ((*(*l_element_courant).donnee).type == CHN) { - if ((argument_majuscule = conversion_majuscule((unsigned char *) - (*(*l_element_courant).donnee).objet)) == NULL) + if ((argument_majuscule = conversion_majuscule(s_etat_processus, + (unsigned char *) (*(*l_element_courant).donnee).objet)) + == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -1186,6 +1430,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 != ' ') @@ -1709,7 +1981,7 @@ instruction_open(struct_processus *s_eta if ((*(*l_element_courant_sous_objet).donnee).type == CHN) { if ((argument_majuscule = conversion_majuscule( - (unsigned char *) + s_etat_processus, (unsigned char *) (*(*l_element_courant_sous_objet) .donnee).objet)) == NULL) { @@ -1775,7 +2047,7 @@ instruction_open(struct_processus *s_eta free(argument_majuscule); if ((argument_majuscule = conversion_majuscule( - (unsigned char *) + s_etat_processus, (unsigned char *) (*(*l_element_courant_sous_objet) .donnee).objet)) == NULL) { @@ -1938,6 +2210,17 @@ 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] = (unsigned char) + (protocole_socket[i] + - ('a' - 'A')); + } + } } else { @@ -2206,6 +2489,29 @@ instruction_open(struct_processus *s_eta } } } + else if (strcmp(argument_majuscule, "STTY") == 0) + { + if ((*(*l_element_courant_sous_objet) + .donnee).type == CHN) + { + 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).donnee; + } + } else { liberation(s_etat_processus, s_objet_argument); @@ -2232,7 +2538,7 @@ instruction_open(struct_processus *s_eta if ((*(*l_element_courant_sous_objet).donnee).type == CHN) { if ((argument_majuscule = conversion_majuscule( - (unsigned char *) + s_etat_processus, (unsigned char *) (*(*l_element_courant_sous_objet) .donnee).objet)) == NULL) { @@ -2273,7 +2579,7 @@ instruction_open(struct_processus *s_eta } if ((argument_majuscule = conversion_majuscule( - (unsigned char *) + s_etat_processus, (unsigned char *) (*(*l_element_courant_sous_objet) .donnee).objet)) == NULL) { @@ -2559,6 +2865,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); @@ -2599,6 +2951,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') { /* @@ -2648,7 +3008,9 @@ instruction_open(struct_processus *s_eta } if (((type_acces != 'I') && (position_clef != 0)) || - ((type_acces == 'I') && (position_clef == 0))) + ((type_acces == 'I') && (position_clef == 0) && + ((type_ouverture == 'N') || (type_ouverture == 'R') || + (type_ouverture == 'S')))) { liberation(s_etat_processus, s_objet_argument); @@ -2684,12 +3046,16 @@ instruction_open(struct_processus *s_eta sprintf(nom, "%s.rpl", nom_temporaire); free(nom_temporaire); - - autorisation_liberation_nom = d_vrai; } else { - autorisation_liberation_nom = d_faux; + if ((nom = transliteration(s_etat_processus, nom, + d_locale, "UTF-8")) == NULL) + { + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + return; + } } /* @@ -2712,6 +3078,8 @@ instruction_open(struct_processus *s_eta if (((*((struct_fichier *) (*s_objet_resultat).objet)).format = allocation(s_etat_processus, LST)) == NULL) { + free(nom); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } @@ -2719,6 +3087,8 @@ instruction_open(struct_processus *s_eta (*(*((struct_fichier *) (*s_objet_resultat).objet)) .format).objet = NULL; + descripteur = NULL; + switch(type_ouverture) { case 'N' : @@ -2728,6 +3098,8 @@ instruction_open(struct_processus *s_eta if ((erreur != 0) || (unite != 0)) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2736,14 +3108,111 @@ instruction_open(struct_processus *s_eta return; } - if ((descripteur = fopen(nom, "w+")) == NULL) + if (type_acces == 'S') { - liberation(s_etat_processus, s_objet_argument); - liberation(s_etat_processus, s_objet_resultat); + if ((descripteur = fopen(nom, "w+")) == NULL) + { + free(nom); - (*s_etat_processus).erreur_execution = - d_ex_erreur_acces_fichier; - return; + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + else + { + // Si le fichier existe, on le supprime. + + if (unlink(nom) != 0) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if ((descripteur = fopen(nom, "a+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if (type_acces == 'D') + { + if (initialisation_fichier_acces_direct( + s_etat_processus, sqlite, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } + else + { + if (position_clef == 0) + { + free(nom); + + 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 (initialisation_fichier_acces_indexe( + s_etat_processus, sqlite, position_clef, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } } break; @@ -2751,11 +3220,13 @@ instruction_open(struct_processus *s_eta case 'O' : { - erreur = caracteristiques_fichier(s_etat_processus, - nom, &existence, &ouverture, &unite); + erreur = caracteristiques_fichier(s_etat_processus, nom, + &existence, &ouverture, &unite); if ((erreur != d_absence_erreur) || (existence == d_faux)) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2764,14 +3235,54 @@ instruction_open(struct_processus *s_eta return; } - if ((descripteur = fopen(nom, "r+")) == NULL) + if (type_acces == 'S') { - liberation(s_etat_processus, s_objet_argument); - liberation(s_etat_processus, s_objet_resultat); + if ((descripteur = fopen(nom, "r+")) == NULL) + { + free(nom); - (*s_etat_processus).erreur_execution = - d_ex_erreur_acces_fichier; - return; + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if ((descripteur = fopen(nom, "a+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } } break; @@ -2784,6 +3295,8 @@ instruction_open(struct_processus *s_eta if ((erreur != d_absence_erreur) || (existence == d_faux)) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2796,6 +3309,8 @@ instruction_open(struct_processus *s_eta if ((descripteur = fopen(nom, "r")) == NULL) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2812,8 +3327,11 @@ instruction_open(struct_processus *s_eta if (fcntl(fileno(descripteur), F_GETLK, &lock) == -1) { + free(nom); + if (fclose(descripteur) != 0) { + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_systeme = @@ -2821,6 +3339,7 @@ instruction_open(struct_processus *s_eta return; } + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_systeme = @@ -2828,8 +3347,33 @@ instruction_open(struct_processus *s_eta return; } + if (lock.l_type != F_UNLCK) + { + free(nom); + + if (fclose(descripteur) != 0) + { + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_fichier_verrouille; + return; + } + if (fclose(descripteur) != 0) { + free(nom); + + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_systeme = @@ -2837,8 +3381,114 @@ instruction_open(struct_processus *s_eta return; } - if ((descripteur = fopen(nom, "w+")) == NULL) + if (type_acces == 'S') { + if ((descripteur = fopen(nom, "w+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + // Ouverture du fichier pour pouvoir gérer les + // verrous à la façon des fichiers séquentiels. + + if ((descripteur = fopen(nom, "a+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if (type_acces == 'D') + { + if (initialisation_fichier_acces_direct( + s_etat_processus, sqlite, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } + else + { + if (position_clef == 0) + { + free(nom); + + 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 (initialisation_fichier_acces_indexe( + s_etat_processus, sqlite, position_clef, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } + } + + break; + } + + case 'U' : + { + erreur = caracteristiques_fichier(s_etat_processus, + nom, &existence, &ouverture, &unite); + + if (erreur == d_erreur) + { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2847,16 +3497,172 @@ instruction_open(struct_processus *s_eta return; } + if (existence == d_faux) + { + if (type_acces == 'S') + { + if ((descripteur = fopen(nom, "w+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if ((descripteur = fopen(nom, "a+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if (type_acces == 'D') + { + if (initialisation_fichier_acces_direct( + s_etat_processus, sqlite, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, + s_objet_argument); + liberation(s_etat_processus, + s_objet_resultat); + + return; + } + } + else + { + if (position_clef == 0) + { + free(nom); + + 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 (initialisation_fichier_acces_indexe( + s_etat_processus, sqlite, position_clef, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, + s_objet_argument); + liberation(s_etat_processus, + s_objet_resultat); + + return; + } + } + } + } + else + { + if (type_acces == 'S') + { + if ((descripteur = fopen(nom, "r+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if ((descripteur = fopen(nom, "a+")) == NULL) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + } + } + break; } - case 'U' : + case 'S' : { erreur = caracteristiques_fichier(s_etat_processus, nom, &existence, &ouverture, &unite); - if (erreur == d_erreur) + if ((erreur != d_absence_erreur) || (existence != d_faux)) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2865,10 +3671,12 @@ instruction_open(struct_processus *s_eta return; } - if (existence == d_faux) + if (type_acces == 'S') { if ((descripteur = fopen(nom, "w+")) == NULL) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2879,8 +3687,45 @@ instruction_open(struct_processus *s_eta } else { - if ((descripteur = fopen(nom, "r+")) == NULL) + // Si le fichier existe, on le supprime. + + if (unlink(nom) != 0) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + 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); + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_execution = + d_ex_erreur_acces_fichier; + return; + } + + if ((descripteur = fopen(nom, "a+")) == NULL) { + free(nom); + liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -2888,52 +3733,692 @@ instruction_open(struct_processus *s_eta d_ex_erreur_acces_fichier; return; } + + if (type_acces == 'D') + { + if (initialisation_fichier_acces_direct( + s_etat_processus, sqlite, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } + else + { + if (position_clef == 0) + { + free(nom); + + 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 (initialisation_fichier_acces_indexe( + s_etat_processus, sqlite, position_clef, + (format == 'N') ? d_faux : d_vrai) + != d_absence_erreur) + { + free(nom); + + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); + + return; + } + } } break; } - case 'S' : + default: { - erreur = caracteristiques_fichier(s_etat_processus, - nom, &existence, &ouverture, &unite); + BUG(1, printf("type_ouverture=%c\n", type_ouverture)); + return; + } + } - if ((erreur != d_absence_erreur) || (existence != d_faux)) + if (((*((struct_fichier *) (*s_objet_resultat).objet)).nom = + malloc((strlen(nom) + 1) * + sizeof(unsigned char))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + 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; + } + + // 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. + + 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( + s_etat_processus, (*(*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[] = + { "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 +#ifdef B460800 + "460800", +#endif +#ifdef B500000 + "500000", +#endif +#ifdef B576000 + "576000", +#endif +#ifdef B921600 + "921600", +#endif +#ifdef B1000000 + "1000000", +#endif +#ifdef B1152000 + "1152000", +#endif + NULL }; + tcflag_t vitesses_constantes[] = + { B50, B75, B110, B134, B150, B200, B300, B600, + B1200, B1800, B2400, B4800, B9600, B19200, B38400, +#ifdef B57600 + B57600, +#endif +#ifdef B115200 + B115200, +#endif +#ifdef B230400 + B230400, +#endif +#ifdef B460800 + B460800, +#endif +#ifdef B500000 + B500000, +#endif +#ifdef B576000 + B576000, +#endif +#ifdef B921600 + B921600, +#endif +#ifdef B1000000 + B1000000, +#endif +#ifdef B1152000 + B1152000, +#endif + 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) + { +#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; + } + } + + 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 &= ~((tcflag_t) CSIZE); + tc.c_cflag |= CS5; + break; + } + + case '6': + { + tc.c_cflag &= ~((tcflag_t) CSIZE); + tc.c_cflag |= CS6; + break; + } + + case '7': + { + tc.c_cflag &= ~((tcflag_t) CSIZE); + tc.c_cflag |= CS7; + break; + } + + case '8': + { + tc.c_cflag &= ~((tcflag_t) 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_acces_fichier; + 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); - if ((descripteur = fopen(nom, "w+")) == NULL) + (*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 &= ~((tcflag_t) PARENB); + break; + } + + case 'O': + { + tc.c_cflag |= PARENB; + tc.c_cflag |= PARODD; + break; + } + + case 'E': + { + tc.c_cflag |= PARENB; + tc.c_cflag &= ~((tcflag_t) 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_acces_fichier; + d_ex_erreur_parametre_fichier; return; } - - break; } - default: + position++; + + if ((*position) != d_code_espace) { - BUG(1, printf("type_ouverture=%c\n", type_ouverture)); + 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 (((*((struct_fichier *) (*s_objet_resultat).objet)).nom = - malloc((strlen(nom) + 1) * - sizeof(unsigned char))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; + // Bits de stop + + while((*position) != d_code_fin_chaine) + { + if (isalnum((*position)) != 0) + { + break; + } + + position++; + } + + switch((*position)) + { + case '1': + { + tc.c_cflag &= ~((tcflag_t) 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. + + position++; + + 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; + + 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( + s_etat_processus, (*(*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", + + "RAW", + + 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_lflag */ + 4, ISIG, 4, ICANON, 4, ECHO, 4, ECHOE, 4, ECHOK, + 4, ECHONL, 4, NOFLSH, 4, TOSTOP, 4, IEXTEN, + + /* RAW */ + 5, 0 }; + 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; + } + + case 5: + { + // RAW ne peut être négatif + 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; + } + + case 5: + { + // no ignbrk + tc.c_iflag &= ~(tcflag_t) IGNBRK; + // no brkint + tc.c_iflag &= ~(tcflag_t) BRKINT; + // no ignpar + tc.c_iflag &= ~(tcflag_t) IGNPAR; + // no parmrk + tc.c_iflag &= ~(tcflag_t) PARMRK; + // no inpck + tc.c_iflag &= ~(tcflag_t) INPCK; + // no istrip + tc.c_iflag &= ~(tcflag_t) ISTRIP; + // no inlcr + tc.c_iflag &= ~(tcflag_t) INLCR; + // no icrnl + tc.c_iflag &= ~(tcflag_t) ICRNL; + // no ixon + tc.c_iflag &= ~(tcflag_t) IXON; + // no ixoff + tc.c_iflag &= ~(tcflag_t) IXOFF; +#ifdef IXANY + // no ixany + tc.c_iflag &= ~(tcflag_t) IXANY; +#endif + // no opost + tc.c_oflag &= ~(tcflag_t) OPOST; + // no isig + tc.c_lflag &= ~(tcflag_t) ISIG; + // no icanon + tc.c_lflag &= ~(tcflag_t) ICANON; + // no echo + tc.c_lflag &= ~(tcflag_t) ECHO; + // no echoe + tc.c_lflag &= ~(tcflag_t) ECHOE; + // no echok + tc.c_lflag &= ~(tcflag_t) ECHOK; + } + } + } + + // On sort si on a trouvé un paramètre + // correct et donc différent de "NO RAW". + + if (!((negation == d_vrai) && + (fonctions_constantes[fonction_courante * 2] + == 5))) + { + break; + } + } + } + + if (fonctions[fonction_courante] == NULL) + { + // Paramètre inconnu + 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); @@ -2944,11 +4429,6 @@ instruction_open(struct_processus *s_eta (*((struct_fichier *) (*s_objet_resultat).objet)).position_clef = position_clef; - if (autorisation_liberation_nom == d_vrai) - { - free(nom); - } - rewind(descripteur); lock.l_type = F_WRLCK; @@ -2963,7 +4443,8 @@ instruction_open(struct_processus *s_eta { liberation(s_etat_processus, s_objet_resultat); - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; return; } @@ -2998,7 +4479,8 @@ instruction_open(struct_processus *s_eta liberation(s_etat_processus, s_objet_resultat); - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; return; } } @@ -3010,6 +4492,8 @@ instruction_open(struct_processus *s_eta if ((lock.l_type == F_RDLCK) && (protection != 'R')) { + free(nom); + if (fclose(descripteur) != 0) { liberation(s_etat_processus, s_objet_resultat); @@ -3027,6 +4511,8 @@ instruction_open(struct_processus *s_eta } else if ((lock.l_type == F_WRLCK) && (protection != 'W')) { + free(nom); + if (fclose(descripteur) != 0) { liberation(s_etat_processus, s_objet_resultat); @@ -3044,6 +4530,17 @@ instruction_open(struct_processus *s_eta } else { + free(nom); + + if (fclose(descripteur) != 0) + { + liberation(s_etat_processus, s_objet_resultat); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_execution = @@ -3087,8 +4584,8 @@ instruction_open(struct_processus *s_eta * Recherche du premier descripteur libre */ - if ((chaine_descripteurs = malloc( - ds_nombre_maximum_fichiers_ouverts + 1)) == NULL) + if ((chaine_descripteurs = malloc(sizeof(unsigned char) * + (ds_nombre_maximum_fichiers_ouverts + 1))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -3130,7 +4627,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 @@ -3166,8 +4663,24 @@ instruction_open(struct_processus *s_eta = prochain_descripteur; (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) .identifiant = prochain_descripteur; - (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) - .descripteur = descripteur; + + if (type_acces == 'S') + { + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) + .type = 'C'; + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) + .descripteur_c = descripteur; + } + else + { + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) + .type = 'S'; + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) + .descripteur_c = descripteur; + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) + .descripteur_sqlite = sqlite; + } + (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) .pid = getpid(); (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) @@ -3175,19 +4688,8 @@ instruction_open(struct_processus *s_eta (*((struct_descripteur_fichier *) (*l_element_courant).donnee)) .effacement = (type_ouverture == 'S') ? 'Y' : 'N'; - if (((*((struct_descripteur_fichier *) (*l_element_courant) - .donnee)).nom = malloc((strlen((*((struct_fichier *) - (*s_objet_resultat).objet)).nom) + 1) * - sizeof(unsigned char))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - strcpy((*((struct_descripteur_fichier *) (*l_element_courant) - .donnee)).nom, (*((struct_fichier *) (*s_objet_resultat) - .objet)).nom); - + (*((struct_descripteur_fichier *) (*l_element_courant) + .donnee)).nom = nom; } else if (type_arguments == 'S') { @@ -3195,222 +4697,6 @@ instruction_open(struct_processus *s_eta * Traitement des sockets */ - - inline logical1 options_socket() - { - /* - * Options des sockets - */ - -# define WARNING(message) \ - if ((*s_etat_processus).langue != 'F') \ - printf("+++Warning : %s unavailable on host system\n", \ - message); \ - else \ - printf("+++Attention : %s non disponible sur le système " \ - "hôte\n", message) - - if (options[d_BIND_TO_DEVICE] == 'Y') - { -# ifdef SO_BINDTODEVICE - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_BINDTODEVICE, - peripherique, strlen(peripherique)) != 0) - { - 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(d_erreur); - } -# else - WARNING("BIND TO DEVICE"); -# endif - } - - if (options[d_BROADCAST] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_BROADCAST, - &drapeau, sizeof(drapeau)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_DONT_ROUTE] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_DONTROUTE, - &drapeau, sizeof(drapeau)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_KEEP_ALIVE] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_KEEPALIVE, - &drapeau, sizeof(drapeau)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_PRIORITY] == 'Y') - { -# ifdef SO_PRIORITY - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_PRIORITY, - &priorite, sizeof(priorite)) != 0) - { - 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(d_erreur); - } -# else - WARNING("PRIORITY"); -# endif - } - - if (options[d_RECEIVE_BUFFER] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_RCVBUF, - &buffer_reception, sizeof(buffer_reception)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_FORCE_RECEIVE_BUFFER] == 'Y') - { -# ifdef SO_RCVBUFFORCE - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_RCVBUFFORCE, - &buffer_reception, sizeof(buffer_reception)) - != 0) - { - 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(d_erreur); - } -# else - WARNING("FORCE_RECEIVE_BUFFER"); -# endif - } - - if (options[d_SEND_BUFFER] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_SNDBUF, - &buffer_emission, sizeof(buffer_emission)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_FORCE_SEND_BUFFER] == 'Y') - { -# ifdef SO_SNDBUFFORCE - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_SNDBUFFORCE, - &buffer_emission, sizeof(buffer_emission)) != 0) - { - 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(d_erreur); - } -# else - WARNING("FORCE_SEND_BUFFER"); -# endif - } - - if (options[d_RECEIVING_TIMEOUT] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_RCVTIMEO, - &timeout_reception, sizeof(timeout_reception)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_SENDING_TIMEOUT] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_SNDTIMEO, - &timeout_emission, sizeof(timeout_emission)) != 0) - { - 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(d_erreur); - } - } - - if (options[d_REUSE_ADDRESS] == 'Y') - { - if (setsockopt((*((struct_socket *) (*s_objet_resultat) - .objet)).socket, SOL_SOCKET, SO_REUSEADDR, - &drapeau, sizeof(drapeau)) != 0) - { - 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(d_erreur); - } - } - - return(d_absence_erreur); -#undef WARNING - } - /* * Vérification de la cohérence des arguments et traitement * des valeurs par défaut. @@ -3497,6 +4783,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 if (strcmp(protocole, "UNIX") != 0) + { + 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'))) { @@ -3528,30 +4836,25 @@ 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; + 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)) @@ -3573,6 +4876,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) { @@ -3605,6 +4909,10 @@ instruction_open(struct_processus *s_eta strcpy((*((struct_socket *) (*s_objet_resultat).objet)). type, "ROBUST DATAGRAM"); break; + + default : + BUG(1, printf("type_socket=%c\n", type_socket)); + break; } if ((protection != 'N') && ((type_socket != 'S') && @@ -3634,16 +4942,13 @@ instruction_open(struct_processus *s_eta else { if (((*((struct_socket *) (*s_objet_resultat).objet)).adresse = - malloc((strlen(nom) + 1) * sizeof(unsigned char))) - == NULL) + transliteration(s_etat_processus, nom, + d_locale, "UTF-8")) == NULL) { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; + liberation(s_etat_processus, s_objet_argument); + liberation(s_etat_processus, s_objet_resultat); return; } - - strcpy((*((struct_socket *) (*s_objet_resultat).objet)).adresse, - nom); } if (((*((struct_socket *) (*s_objet_resultat).objet)) @@ -3669,6 +4974,7 @@ instruction_open(struct_processus *s_eta = 'Y'; (*((struct_socket *) (*s_objet_resultat).objet)).socket_connectee = d_faux; + (*((struct_socket *) (*s_objet_resultat).objet)).options = 0; if (type_domaine == 'L') { // Socket serveur @@ -3705,10 +5011,13 @@ 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) + if (options_socket(s_etat_processus, s_objet_resultat, + options, peripherique, &priorite, + &buffer_emission, &buffer_reception, + &timeout_emission, &timeout_reception) == d_erreur) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -3812,7 +5121,12 @@ instruction_open(struct_processus *s_eta (*resolution_courante).ai_addr)) .sin_addr.s_addr; - if (options_socket() == d_erreur) + if (options_socket(s_etat_processus, + s_objet_resultat, + options, peripherique, &priorite, + &buffer_emission, &buffer_reception, + &timeout_emission, &timeout_reception) + == d_erreur) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -3835,8 +5149,11 @@ 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 * + .objet)).adresse = malloc(23 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -3845,7 +5162,7 @@ instruction_open(struct_processus *s_eta } sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%d.%d.%d.%d", + .objet)).adresse, "%d.%d.%d.%d(%u)", (ntohl((*((struct sockaddr_in *) (*resolution_courante).ai_addr)).sin_addr .s_addr) >> 24) & 0xFF, @@ -3857,10 +5174,12 @@ instruction_open(struct_processus *s_eta .s_addr) >> 8) & 0xFF, ntohl((*((struct sockaddr_in *) (*resolution_courante).ai_addr)).sin_addr - .s_addr) & 0xFF); + .s_addr) & 0xFF, + (unsigned int) port); } else { // Accès en IPv6 +# ifdef IPV6 resolution_courante = resolution; while(resolution_courante != NULL) @@ -3915,7 +5234,12 @@ instruction_open(struct_processus *s_eta (*resolution_courante).ai_addr)) .sin6_addr.s6_addr[i], i++); - if (options_socket() == d_erreur) + if (options_socket(s_etat_processus, + s_objet_resultat, + options, peripherique, &priorite, + &buffer_emission, &buffer_reception, + &timeout_emission, &timeout_reception) + == d_erreur) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -3938,8 +5262,22 @@ instruction_open(struct_processus *s_eta return; } + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + + /* + * Longueur de la chaîne : + * Adresse IPv6 : 16 octets soit 128 bits. + * => 32 chiffres en hexadécimal + * Par groupe de 4, 8 groupes + * => 7 ":" + * Port : (%u) + * => 7 + * ==> 32 + 7 + 7 + 1 = 47 + */ + if (((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse = malloc(55 * + .objet)).adresse = malloc(47 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -3947,32 +5285,93 @@ instruction_open(struct_processus *s_eta return; } - for(i = 0; i < 16; i++) + sprintf((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse, + "%02X%02X:%02X%02X:%02X%02X:%02X%02X:" + "%02X%02X:%02X%02X:%02X%02X:%02X%02X(%u)", + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[0], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[1], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[2], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[3], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[4], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[5], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[6], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[7], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[8], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[9], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[10], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[11], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[12], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[13], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[14], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[15], + (unsigned int) port); +# else + if ((*s_etat_processus).langue == 'F') { - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (i == 0) ? "%s%X" : "%s:%X", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (*((struct sockaddr_in6 *) - (*resolution_courante).ai_addr)) - .sin6_addr.s6_addr[i]); + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + 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 } freeaddrinfo(resolution); - - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); } else { // 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 * + .objet)).adresse = malloc(23 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -3980,22 +5379,11 @@ instruction_open(struct_processus *s_eta return; } - (*((struct_socket *) (*s_objet_resultat).objet)) - .adresse[0] = d_code_fin_chaine; - - for(i = 0; i < 4; i++) - { - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (i == 0) ? "%s%d" : "%s.%d", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (int) adresse[i]); - } - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); + .objet)).adresse, "%d.%d.%d.%d(%u)", + (int) adresse[0], (int) adresse[1], + (int) adresse[2], (int) adresse[3], + (unsigned int) port); if (((*((struct_socket *) (*s_objet_resultat).objet)) @@ -4019,11 +5407,17 @@ 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); - if (options_socket() == d_erreur) + if (options_socket(s_etat_processus, + s_objet_resultat, + options, peripherique, &priorite, + &buffer_emission, &buffer_reception, + &timeout_emission, &timeout_reception) + == d_erreur) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -4045,8 +5439,12 @@ 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 * + .objet)).adresse = malloc(47 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4054,23 +5452,27 @@ instruction_open(struct_processus *s_eta return; } - (*((struct_socket *) (*s_objet_resultat).objet)) - .adresse[0] = d_code_fin_chaine; - - for(i = 0; i < 16; i++) - { - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (i == 0) ? "%s%X" : "%s:%X", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) - adresse[i]); - } - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); + .objet)).adresse, + "%02X%02X:%02X%02X:%02X%02X:%02X%02X:" + "%02X%02X:%02X%02X:%02X%02X:%02X%02X(%u)", + (unsigned int) adresse[0], + (unsigned int) adresse[1], + (unsigned int) adresse[2], + (unsigned int) adresse[3], + (unsigned int) adresse[4], + (unsigned int) adresse[5], + (unsigned int) adresse[6], + (unsigned int) adresse[7], + (unsigned int) adresse[8], + (unsigned int) adresse[9], + (unsigned int) adresse[10], + (unsigned int) adresse[11], + (unsigned int) adresse[12], + (unsigned int) adresse[13], + (unsigned int) adresse[14], + (unsigned int) adresse[15], + (unsigned int) port); if (((*((struct_socket *) (*s_objet_resultat).objet)) @@ -4096,7 +5498,12 @@ instruction_open(struct_processus *s_eta socket_ipv6.sin6_addr.s6_addr[i] = (unsigned char) (adresse[i]), i++); - if (options_socket() == d_erreur) + if (options_socket(s_etat_processus, + s_objet_resultat, + options, peripherique, &priorite, + &buffer_emission, &buffer_reception, + &timeout_emission, &timeout_reception) + == d_erreur) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); @@ -4115,6 +5522,25 @@ instruction_open(struct_processus *s_eta d_ex_erreur_acces_fichier; return; } +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + 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 } } @@ -4218,8 +5644,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')) { @@ -4347,8 +5773,11 @@ 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 * + .objet)).adresse = malloc(23 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4357,7 +5786,7 @@ instruction_open(struct_processus *s_eta } sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%d.%d.%d.%d", + .objet)).adresse, "%d.%d.%d.%d(%u)", (ntohl((*((struct sockaddr_in *) (*resolution_courante).ai_addr)).sin_addr .s_addr) >> 24) & 0xFF, @@ -4369,10 +5798,12 @@ instruction_open(struct_processus *s_eta .s_addr) >> 8) & 0xFF, ntohl((*((struct sockaddr_in *) (*resolution_courante).ai_addr)).sin_addr - .s_addr) & 0xFF); + .s_addr) & 0xFF, + (unsigned int) port); } else { // Accès en IPv6 +# ifdef IPV6 resolution_courante = resolution; while(resolution_courante != NULL) @@ -4452,8 +5883,11 @@ 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 * + .objet)).adresse = malloc(47 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4461,25 +5895,83 @@ instruction_open(struct_processus *s_eta return; } - for(i = 0; i < 16; i++) + sprintf((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse, + "%02X%02X:%02X%02X:%02X%02X:%02X%02X:" + "%02X%02X:%02X%02X:%02X%02X:%02X%02X(%u)", + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[0], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[1], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[2], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[3], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[4], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[5], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[6], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[7], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[8], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[9], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[10], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[11], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[12], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[13], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[14], + (*((struct sockaddr_in6 *) + (*resolution_courante).ai_addr)).sin6_addr + .s6_addr[15], + (unsigned int) port); +# else + if ((*s_etat_processus).langue == 'F') { - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (i == 0) ? "%s%X" : "%s:%X", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, - (*((struct sockaddr_in6 *) - (*resolution_courante).ai_addr)) - .sin6_addr.s6_addr[i]); + printf("+++Attention : Support du protocole" + " IPv6 indisponible\n"); + } + else + { + 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 } freeaddrinfo(resolution); - - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); } else { // Hôte défini par une adresse @@ -4487,8 +5979,11 @@ 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 * + .objet)).adresse = malloc(23 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4496,26 +5991,17 @@ instruction_open(struct_processus *s_eta return; } - (*((struct_socket *) (*s_objet_resultat).objet)) - .adresse[0] = d_code_fin_chaine; - - for(i = 0; i < 4; i++) - { - sprintf((*((struct_socket *) - (*s_objet_resultat).objet)).adresse, - (i == 0) ? "%s%d" : "%s.%d", - (*((struct_socket *) - (*s_objet_resultat) - .objet)).adresse, (int) adresse[i]); - } - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); + .objet)).adresse, "%d.%d.%d.%d(%u)", + (int) adresse[0], (int) adresse[1], + (int) adresse[2], (int) adresse[3], + (unsigned int) port); } else { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc( sizeof(unsigned char))) == NULL) @@ -4551,7 +6037,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); @@ -4580,10 +6067,14 @@ instruction_open(struct_processus *s_eta } else if (strcmp(protocole, "IPV6") == 0) { // Accès en IPv6 +# ifdef IPV6 if (type_adresse == '6') { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse = malloc(55 * + .objet)).adresse = malloc(47 * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = @@ -4591,27 +6082,34 @@ instruction_open(struct_processus *s_eta return; } - (*((struct_socket *) (*s_objet_resultat).objet)) - .adresse[0] = d_code_fin_chaine; - - for(i = 0; i < 16; i++) - { - sprintf((*((struct_socket *) - (*s_objet_resultat).objet)).adresse, - (i == 0) ? "%s%X" : "%s:%X", - (*((struct_socket *) - (*s_objet_resultat) - .objet)).adresse, (unsigned int) - adresse[i]); - } - sprintf((*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, "%s(%u)", - (*((struct_socket *) (*s_objet_resultat) - .objet)).adresse, (unsigned int) port); + .objet)).adresse, + "%02X%02X:%02X%02X:%02X%02X:%02X%02X:" + "%02X%02X:%02X%02X:%02X%02X:%02X%02X" + "(%u)", + (unsigned int) adresse[0], + (unsigned int) adresse[1], + (unsigned int) adresse[2], + (unsigned int) adresse[3], + (unsigned int) adresse[4], + (unsigned int) adresse[5], + (unsigned int) adresse[6], + (unsigned int) adresse[7], + (unsigned int) adresse[8], + (unsigned int) adresse[9], + (unsigned int) adresse[10], + (unsigned int) adresse[11], + (unsigned int) adresse[12], + (unsigned int) adresse[13], + (unsigned int) adresse[14], + (unsigned int) adresse[15], + (unsigned int) port); } else { + free((*((struct_socket *) (*s_objet_resultat) + .objet)).adresse); + if (((*((struct_socket *) (*s_objet_resultat) .objet)).adresse = malloc( sizeof(unsigned char))) == NULL) @@ -4671,9 +6169,31 @@ instruction_open(struct_processus *s_eta (*((struct_socket *) (*s_objet_resultat).objet)) .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"); + } + + 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) @@ -4787,6 +6307,8 @@ instruction_open(struct_processus *s_eta (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } + + liberation(s_etat_processus, s_objet_argument); } else {