1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.36
4: Copyright (C) 1989-2025 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Fonction de récupération des paramètres de connexion à une base SQL
29: ================================================================================
30: Entrées : objet de type liste
31: --------------------------------------------------------------------------------
32: Sorties : pointeur sur un struct_connecteur_swl
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: struct_objet *
39: parametres_sql(struct_processus *s_etat_processus, struct_objet *s_parametres)
40: {
41: struct_liste_chainee *l_element_courant;
42:
43: struct_objet *s_connecteur;
44:
45: unsigned char *locale;
46: unsigned char *type_base;
47: unsigned char *serveur;
48: # if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT)
49: unsigned char *base;
50: unsigned char *utilisateur;
51: unsigned char *mot_de_passe;
52: # ifdef POSTGRESQL_SUPPORT
53: unsigned char *sport;
54: # endif
55:
56: unsigned int port;
57: # endif
58:
59: if ((*s_parametres).type != LST)
60: {
61: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
62: return(NULL);
63: }
64:
65: l_element_courant = (struct_liste_chainee *) (*s_parametres).objet;
66:
67: if (l_element_courant == NULL)
68: {
69: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
70: return(NULL);
71: }
72:
73: if ((*(*l_element_courant).donnee).type != CHN)
74: {
75: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
76: return(NULL);
77: }
78:
79: if ((type_base = conversion_majuscule(s_etat_processus, (unsigned char *)
80: (*(*l_element_courant).donnee).objet)) == NULL)
81: {
82: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
83: return(NULL);
84: }
85:
86: locale = index(type_base, ':');
87:
88: if (locale != NULL)
89: {
90: (*locale) = d_code_fin_chaine;
91: locale++;
92: }
93:
94: /*
95: * Vérifications des types de base de données
96: */
97:
98: if ((strcmp(type_base, "MYSQL") != 0) &&
99: (strcmp(type_base, "POSTGRESQL") != 0) &&
100: (strcmp(type_base, "SQLITE") != 0))
101: {
102: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
103: return(NULL);
104: }
105:
106: if ((s_connecteur = allocation(s_etat_processus, SQL)) == NULL)
107: {
108: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
109: return(NULL);
110: }
111:
112: (*((struct_connecteur_sql *) (*s_connecteur).objet)).type = type_base;
113:
114: if (locale != NULL)
115: {
116: if (((*((struct_connecteur_sql *) (*s_connecteur).objet)).locale
117: = malloc((strlen(locale) + 1) * sizeof(unsigned char))) == NULL)
118: {
119: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
120: return(NULL);
121: }
122:
123: strcpy((*((struct_connecteur_sql *) (*s_connecteur).objet)).locale,
124: locale);
125:
126: if (((*((struct_connecteur_sql *) (*s_connecteur).objet)).type
127: = realloc((*((struct_connecteur_sql *) (*s_connecteur).objet))
128: .type, (strlen((*((struct_connecteur_sql *) (*s_connecteur)
129: .objet)).type) + 1) * sizeof(unsigned char))) == NULL)
130: {
131: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
132: return(NULL);
133: }
134: }
135: else
136: {
137: (*((struct_connecteur_sql *) (*s_connecteur).objet)).locale = NULL;
138: }
139:
140: (*((struct_connecteur_sql *) (*s_connecteur).objet)).pid = getpid();
141: (*((struct_connecteur_sql *) (*s_connecteur).objet)).tid = pthread_self();
142:
143: // Recherche du nom ou de l'adresse du serveur
144:
145: l_element_courant = (*l_element_courant).suivant;
146:
147: if (l_element_courant == NULL)
148: {
149: liberation(s_etat_processus, s_connecteur);
150: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
151: return(NULL);
152: }
153:
154: if ((*(*l_element_courant).donnee).type != CHN)
155: {
156: liberation(s_etat_processus, s_connecteur);
157: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
158: return(NULL);
159: }
160:
161: serveur = (unsigned char *) (*(*l_element_courant).donnee).objet;
162:
163: // Dans le cas d'une base de données SQLite, seul le nom du fichier
164: // importe.
165:
166: if (strcmp(type_base, "SQLITE") == 0)
167: {
168: if ((*l_element_courant).suivant != NULL)
169: {
170: liberation(s_etat_processus, s_connecteur);
171: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
172: return(NULL);
173: }
174:
175: (*((struct_connecteur_sql *) (*s_connecteur).objet)).descripteur.sqlite
176: = NULL;
177:
178: if (sqlite3_open_v2(serveur, &((*((struct_connecteur_sql *)
179: (*s_connecteur).objet)).descripteur.sqlite),
180: SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK)
181: {
182: if ((*((struct_connecteur_sql *) (*s_connecteur).objet))
183: .descripteur.sqlite != NULL)
184: {
185: sqlite3_close((*((struct_connecteur_sql *)
186: (*s_connecteur).objet)).descripteur.sqlite);
187: }
188:
189: liberation(s_etat_processus, s_connecteur);
190: (*s_etat_processus).erreur_execution = d_ex_erreur_sql;
191: return(NULL);
192: }
193:
194: return(s_connecteur);
195: }
196: else
197: {
198: # if !(defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT))
199: if ((*s_etat_processus).langue == 'F')
200: {
201: printf("+++Attention : Support de %s non compilé !\n", type_base);
202: }
203: else
204: {
205: printf("+++Warning : %s support not available !\n", type_base);
206: }
207: # endif
208: }
209:
210: # if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT)
211: // Recherche du nom de la base de données
212:
213: l_element_courant = (*l_element_courant).suivant;
214:
215: if (l_element_courant == NULL)
216: {
217: liberation(s_etat_processus, s_connecteur);
218: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
219: return(NULL);
220: }
221:
222: if ((*(*l_element_courant).donnee).type != CHN)
223: {
224: liberation(s_etat_processus, s_connecteur);
225: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
226: return(NULL);
227: }
228:
229: base = (unsigned char *) (*(*l_element_courant).donnee).objet;
230:
231: // Recherche de l'utilisateur
232:
233: l_element_courant = (*l_element_courant).suivant;
234:
235: if (l_element_courant == NULL)
236: {
237: liberation(s_etat_processus, s_connecteur);
238: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
239: return(NULL);
240: }
241:
242: if ((*(*l_element_courant).donnee).type != CHN)
243: {
244: liberation(s_etat_processus, s_connecteur);
245: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
246: return(NULL);
247: }
248:
249: utilisateur = (unsigned char *) (*(*l_element_courant).donnee).objet;
250:
251: // Recherche du mot de passe
252:
253: l_element_courant = (*l_element_courant).suivant;
254:
255: if (l_element_courant == NULL)
256: {
257: liberation(s_etat_processus, s_connecteur);
258: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
259: return(NULL);
260: }
261:
262: if ((*(*l_element_courant).donnee).type != CHN)
263: {
264: liberation(s_etat_processus, s_connecteur);
265: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
266: return(NULL);
267: }
268:
269: mot_de_passe = (unsigned char *) (*(*l_element_courant).donnee).objet;
270:
271: // Recherche du port le cas échéant
272:
273: l_element_courant = (*l_element_courant).suivant;
274:
275: if (l_element_courant != NULL)
276: {
277: if ((*(*l_element_courant).donnee).type != INT)
278: {
279: liberation(s_etat_processus, s_connecteur);
280: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
281: return(NULL);
282: }
283:
284: if (((*((integer8 *) (*(*l_element_courant).donnee).objet)) < 0)
285: || ((*((integer8 *) (*(*l_element_courant).donnee)
286: .objet)) > 65535))
287: {
288: liberation(s_etat_processus, s_connecteur);
289: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
290: return(NULL);
291: }
292:
293: port = (unsigned int) (*((integer8 *)
294: (*(*l_element_courant).donnee).objet));
295:
296: if ((*l_element_courant).suivant != NULL)
297: {
298: liberation(s_etat_processus, s_connecteur);
299: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
300: return(NULL);
301: }
302: }
303: else
304: {
305: port = 0;
306: }
307:
308: if (strcmp((*((struct_connecteur_sql *) (*s_connecteur).objet)).type,
309: "MYSQL") == 0)
310: {
311: # ifdef MYSQL_SUPPORT
312: (*((struct_connecteur_sql *) (*s_connecteur).objet))
313: .descripteur.mysql = NULL;
314:
315: if (((*((struct_connecteur_sql *) (*s_connecteur).objet))
316: .descripteur.mysql = mysql_init(NULL)) == NULL)
317: {
318: liberation(s_etat_processus, s_connecteur);
319: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
320: return(NULL);
321: }
322:
323: if (mysql_real_connect((*((struct_connecteur_sql *) (*s_connecteur)
324: .objet)).descripteur.mysql, serveur, utilisateur, mot_de_passe,
325: base, port, NULL, 0) == NULL)
326: {
327: mysql_close((*((struct_connecteur_sql *) (*s_connecteur).objet))
328: .descripteur.mysql);
329:
330: liberation(s_etat_processus, s_connecteur);
331: (*s_etat_processus).erreur_execution = d_ex_erreur_sql;
332: return(NULL);
333: }
334: # else
335: if ((*s_etat_processus).langue == 'F')
336: {
337: printf("+++Attention : Support de MySQL non compilé !\n");
338: }
339: else
340: {
341: printf("+++Warning : MySQL support not available !\n");
342: }
343:
344: fflush(stdout);
345:
346: (*s_etat_processus).erreur_execution = d_ex_instruction_indisponible;
347: # endif
348: }
349: else if (strcmp((*((struct_connecteur_sql *) (*s_connecteur).objet)).type,
350: "POSTGRESQL") == 0)
351: {
352: # ifdef POSTGRESQL_SUPPORT
353: if (port == 0)
354: {
355: sport = NULL;
356: }
357: else
358: {
359: if ((sport = malloc(32 * sizeof(unsigned char))) == NULL)
360: {
361: liberation(s_etat_processus, s_connecteur);
362: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
363: return(NULL);
364: }
365:
366: sprintf(sport, "%u", port);
367: }
368:
369: (*((struct_connecteur_sql *) (*s_connecteur).objet)).descripteur
370: .postgresql = PQsetdbLogin(serveur, sport, NULL, NULL,
371: base, utilisateur, mot_de_passe);
372:
373: free(sport);
374:
375: if (PQstatus((*((struct_connecteur_sql *) (*s_connecteur).objet))
376: .descripteur.postgresql) != CONNECTION_OK)
377: {
378: PQfinish((*((struct_connecteur_sql *) (*s_connecteur).objet))
379: .descripteur.postgresql);
380:
381: liberation(s_etat_processus, s_connecteur);
382: (*s_etat_processus).erreur_execution = d_ex_erreur_sql;
383: return(NULL);
384: }
385: # else
386: if ((*s_etat_processus).langue == 'F')
387: {
388: printf("+++Attention : Support de PostgreSQL non compilé !\n");
389: }
390: else
391: {
392: printf("+++Warning : PostgreSQL support not available !\n");
393: }
394:
395: fflush(stdout);
396:
397: (*s_etat_processus).erreur_execution = d_ex_instruction_indisponible;
398: # endif
399: }
400: else
401: {
402: liberation(s_etat_processus, s_connecteur);
403: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
404: return(NULL);
405: }
406: # endif
407:
408: return(s_connecteur);
409: }
410:
411: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>