source: ogServer-Git/src/ogAdmServer.c

Last change on this file was 216986e, checked in by OpenGnSys Support Team <soporte-og@…>, 2 years ago

#915 consolidate WoL sender function

This patch aims simplifies the WoL sender routine.

A few related changes:

  • Replace goto err to continue if IP address is malformed
  • Use ret |= instead of ret &= to accumulate error code.
  • Property mode set to 100644
File size: 31.0 KB
Line 
1// *******************************************************************************************************
2// Servicio: ogAdmServer
3// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
4// Fecha Creación: Marzo-2010
5// Fecha Última modificación: Marzo-2010
6// Nombre del fichero: ogAdmServer.cpp
7// Descripción :Este fichero implementa el servicio de administración general del sistema
8// *******************************************************************************************************
9#include "ogAdmServer.h"
10#include "dbi.h"
11#include "utils.h"
12#include "list.h"
13#include "rest.h"
14#include "client.h"
15#include "json.h"
16#include "schedule.h"
17#include "wol.h"
18#include <syslog.h>
19#include <sys/ioctl.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <jansson.h>
24#include <time.h>
25
26// ________________________________________________________________________________________________________
27// Función: actualizaConfiguracion
28//
29//      Descripción:
30//              Esta función actualiza la base de datos con la configuracion de particiones de un cliente
31//      Parámetros:
32//              - db: Objeto base de datos (ya operativo)
33//              - tbl: Objeto tabla
34//              - cfg: cadena con una Configuración
35//              - ido: Identificador del ordenador cliente
36//      Devuelve:
37//              true: Si el proceso es correcto
38//              false: En caso de ocurrir algún error
39//      Especificaciones:
40//              Los parametros de la configuración son:
41//                      par= Número de partición
42//                      cpt= Codigo o tipo de partición
43//                      sfi= Sistema de ficheros que está implementado en la partición
44//                      soi= Nombre del sistema de ficheros instalado en la partición
45//                      tam= Tamaño de la partición
46// ________________________________________________________________________________________________________
47bool actualizaConfiguracion(struct og_dbi *dbi, char *cfg, int ido)
48{
49        int lon, p, c,i, dato, swu, idsoi, idsfi,k;
50        char *ptrPar[MAXPAR], *ptrCfg[8], *ptrDual[2], tbPar[LONSTD];
51        char *ser, *disk, *disk_type, *par, *cpt, *sfi, *soi, *tam, *uso; // Parametros de configuración.
52        dbi_result result, result_update;
53        const char *msglog;
54
55        lon = 0;
56        p = splitCadena(ptrPar, cfg, '\n');
57        for (i = 0; i < p; i++) {
58                c = splitCadena(ptrCfg, ptrPar[i], '\t');
59
60                // Si la 1ª línea solo incluye el número de serie del equipo; actualizar BD.
61                if (i == 0 && c == 1) {
62                        splitCadena(ptrDual, ptrCfg[0], '=');
63                        ser = ptrDual[1];
64                        if (ser && strlen(ser) > 0) {
65                                // Solo actualizar si número de serie no existía.
66                                result = dbi_conn_queryf(dbi->conn,
67                                                "UPDATE ordenadores SET numserie='%s'"
68                                                " WHERE idordenador=%d AND numserie IS NULL",
69                                                ser, ido);
70                                if (!result) {
71                                        dbi_conn_error(dbi->conn, &msglog);
72                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
73                                               __func__, __LINE__, msglog);
74                                        return false;
75                                }
76                                dbi_result_free(result);
77                        }
78                        continue;
79                }
80
81                // Distribución de particionado.
82                disk = disk_type = par = cpt = sfi = soi = tam = uso = NULL;
83
84                splitCadena(ptrDual, ptrCfg[0], '=');
85                disk = ptrDual[1]; // Número de disco
86
87                splitCadena(ptrDual, ptrCfg[1], '=');
88                par = ptrDual[1]; // Número de partición
89
90                k=splitCadena(ptrDual, ptrCfg[2], '=');
91                if(k==2){
92                        cpt = ptrDual[1]; // Código de partición
93                }else{
94                        cpt = (char*)"0";
95                }
96
97                k=splitCadena(ptrDual, ptrCfg[3], '=');
98                if(k==2){
99                        sfi = ptrDual[1]; // Sistema de ficheros
100                        /* Comprueba existencia del s0xistema de ficheros instalado */
101                        idsfi = checkDato(dbi, sfi, "sistemasficheros", "descripcion","idsistemafichero");
102                }
103                else
104                        idsfi=0;
105
106                k=splitCadena(ptrDual, ptrCfg[4], '=');
107                if(k==2){ // Sistema operativo detecdtado
108                        soi = ptrDual[1]; // Nombre del S.O. instalado
109                        /* Comprueba existencia del sistema operativo instalado */
110                        idsoi = checkDato(dbi, soi, "nombresos", "nombreso", "idnombreso");
111                }
112                else
113                        idsoi=0;
114
115                splitCadena(ptrDual, ptrCfg[5], '=');
116                tam = ptrDual[1]; // Tamaño de la partición
117
118                splitCadena(ptrDual, ptrCfg[6], '=');
119                uso = ptrDual[1]; // Porcentaje de uso del S.F.
120
121                k = splitCadena(ptrDual, ptrCfg[7], '=');
122                if (k == 2)
123                        disk_type = ptrDual[1];
124                else
125                        disk_type = NULL;
126
127                lon += sprintf(tbPar + lon, "(%s, %s),", disk, par);
128
129                result = dbi_conn_queryf(dbi->conn,
130                                "SELECT numdisk, numpar, tamano, uso, idsistemafichero, idnombreso"
131                                "  FROM ordenadores_particiones"
132                                " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
133                                ido, disk, par);
134                if (!result) {
135                        dbi_conn_error(dbi->conn, &msglog);
136                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
137                               __func__, __LINE__, msglog);
138                        return false;
139                }
140                if (!dbi_result_next_row(result)) {
141                        result_update = dbi_conn_queryf(dbi->conn,
142                                        "INSERT INTO ordenadores_particiones(idordenador,numdisk,disk_type,numpar,codpar,tamano,uso,idsistemafichero,idnombreso,idimagen)"
143                                        " VALUES(%d,%s,'%s',%s,0x%s,%s,%s,%d,%d,0)",
144                                        ido, disk, disk_type, par, cpt, tam, uso, idsfi, idsoi);
145                        if (!result_update) {
146                                dbi_conn_error(dbi->conn, &msglog);
147                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
148                                       __func__, __LINE__, msglog);
149                                return false;
150                        }
151                        dbi_result_free(result_update);
152
153                } else { // Existe el registro
154                        swu = true; // Se supone que algún dato ha cambiado
155
156                        dato = dbi_result_get_longlong(result, "tamano");
157                        if (atoi(tam) == dato) {// Parámetro tamaño igual al almacenado
158                                dato = dbi_result_get_uint(result, "idsistemafichero");
159                                if (idsfi == dato) {// Parámetro sistema de fichero igual al almacenado
160                                        dato = dbi_result_get_uint(result, "idnombreso");
161                                        if (idsoi == dato) {// Parámetro sistema de fichero distinto al almacenado
162                                                swu = false; // Todos los parámetros de la partición son iguales, no se actualiza
163                                        }
164                                }
165                        }
166                        if (swu) { // Hay que actualizar los parámetros de la partición
167                                result_update = dbi_conn_queryf(dbi->conn,
168                                        "UPDATE ordenadores_particiones SET "
169                                        " codpar=0x%s,"
170                                        " tamano=%s,"
171                                        " uso=%s,"
172                                        " idsistemafichero=%d,"
173                                        " idnombreso=%d,"
174                                        " idimagen=0,"
175                                        " idperfilsoft=0,"
176                                        " fechadespliegue=NULL"
177                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
178                                        cpt, tam, uso, idsfi, idsoi, ido, disk, par);
179                        } else {  // Actualizar porcentaje de uso.
180                                result_update = dbi_conn_queryf(dbi->conn,
181                                        "UPDATE ordenadores_particiones SET "
182                                        " codpar=0x%s,"
183                                        " uso=%s"
184                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
185                                        cpt, uso, ido, disk, par);
186                        }
187                        if (!result_update) {
188                                dbi_conn_error(dbi->conn, &msglog);
189                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
190                                       __func__, __LINE__, msglog);
191                                return false;
192                        }
193
194                        dbi_result_free(result_update);
195                }
196                dbi_result_free(result);
197        }
198        lon += sprintf(tbPar + lon, "(0,0)");
199        // Eliminar particiones almacenadas que ya no existen
200        result_update = dbi_conn_queryf(dbi->conn,
201                "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)",
202                        ido, tbPar);
203        if (!result_update) {
204                dbi_conn_error(dbi->conn, &msglog);
205                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
206                       __func__, __LINE__, msglog);
207                return false;
208        }
209        dbi_result_free(result_update);
210
211        return true;
212}
213// ________________________________________________________________________________________________________
214// Función: checkDato
215//
216//      Descripción:
217//               Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en
218//              cualquier caso el identificador del registro existenet o del insertado
219//      Parámetros:
220//              - db: Objeto base de datos (ya operativo)
221//              - tbl: Objeto tabla
222//              - dato: Dato
223//              - tabla: Nombre de la tabla
224//              - nomdato: Nombre del dato en la tabla
225//              - nomidentificador: Nombre del identificador en la tabla
226//      Devuelve:
227//              El identificador del registro existente o el del insertado
228//
229//      Especificaciones:
230//              En caso de producirse algún error se devuelve el valor 0
231// ________________________________________________________________________________________________________
232
233int checkDato(struct og_dbi *dbi, char *dato, const char *tabla,
234                     const char *nomdato, const char *nomidentificador)
235{
236        const char *msglog;
237        int identificador;
238        dbi_result result;
239
240        if (strlen(dato) == 0)
241                return (0); // EL dato no tiene valor
242        result = dbi_conn_queryf(dbi->conn,
243                        "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador,
244                        tabla, nomdato, dato);
245
246        // Ejecuta consulta
247        if (!result) {
248                dbi_conn_error(dbi->conn, &msglog);
249                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
250                       __func__, __LINE__, msglog);
251                return (0);
252        }
253        if (!dbi_result_next_row(result)) { //  Software NO existente
254                dbi_result_free(result);
255
256                result = dbi_conn_queryf(dbi->conn,
257                                "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato);
258                if (!result) {
259                        dbi_conn_error(dbi->conn, &msglog);
260                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
261                               __func__, __LINE__, msglog);
262                        return (0);
263                }
264                // Recupera el identificador del software
265                identificador = dbi_conn_sequence_last(dbi->conn, NULL);
266        } else {
267                identificador = dbi_result_get_uint(result, nomidentificador);
268        }
269        dbi_result_free(result);
270
271        return (identificador);
272}
273
274// ________________________________________________________________________________________________________
275// Función: actualizaCreacionImagen
276//
277//      Descripción:
278//              Esta función actualiza la base de datos con el resultado de la creación de una imagen
279//      Parámetros:
280//              - db: Objeto base de datos (ya operativo)
281//              - tbl: Objeto tabla
282//              - idi: Identificador de la imagen
283//              - dsk: Disco de donde se creó
284//              - par: Partición de donde se creó
285//              - cpt: Código de partición
286//              - ipr: Ip del repositorio
287//              - ido: Identificador del ordenador modelo
288//      Devuelve:
289//              true: Si el proceso es correcto
290//              false: En caso de ocurrir algún error
291// ________________________________________________________________________________________________________
292bool actualizaCreacionImagen(struct og_dbi *dbi, char *idi, char *dsk,
293                             char *par, char *cpt, char *ipr, char *ido)
294{
295        const char *msglog;
296        dbi_result result;
297        int idr,ifs;
298
299        /* Toma identificador del repositorio correspondiente al ordenador modelo */
300        result = dbi_conn_queryf(dbi->conn,
301                        "SELECT repositorios.idrepositorio"
302                        "  FROM repositorios"
303                        "  LEFT JOIN ordenadores USING (idrepositorio)"
304                        " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
305
306        if (!result) {
307                dbi_conn_error(dbi->conn, &msglog);
308                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
309                       __func__, __LINE__, msglog);
310                return false;
311        }
312        if (!dbi_result_next_row(result)) {
313                syslog(LOG_ERR,
314                       "repository does not exist in database (%s:%d)\n",
315                       __func__, __LINE__);
316                dbi_result_free(result);
317                return false;
318        }
319        idr = dbi_result_get_uint(result, "idrepositorio");
320        dbi_result_free(result);
321
322        /* Toma identificador del perfilsoftware */
323        result = dbi_conn_queryf(dbi->conn,
324                        "SELECT idperfilsoft"
325                        "  FROM ordenadores_particiones"
326                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
327
328        if (!result) {
329                dbi_conn_error(dbi->conn, &msglog);
330                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
331                       __func__, __LINE__, msglog);
332                return false;
333        }
334        if (!dbi_result_next_row(result)) {
335                syslog(LOG_ERR,
336                       "software profile does not exist in database (%s:%d)\n",
337                       __func__, __LINE__);
338                dbi_result_free(result);
339                return false;
340        }
341        ifs = dbi_result_get_uint(result, "idperfilsoft");
342        dbi_result_free(result);
343
344        /* Actualizar los datos de la imagen */
345        result = dbi_conn_queryf(dbi->conn,
346                "UPDATE imagenes"
347                "   SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
348                "       idperfilsoft=%d, idrepositorio=%d,"
349                "       fechacreacion=NOW(), revision=revision+1"
350                " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
351
352        if (!result) {
353                dbi_conn_error(dbi->conn, &msglog);
354                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
355                       __func__, __LINE__, msglog);
356                return false;
357        }
358        dbi_result_free(result);
359
360        /* Actualizar los datos en el cliente */
361        result = dbi_conn_queryf(dbi->conn,
362                "UPDATE ordenadores_particiones"
363                "   SET idimagen=%s, revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
364                "       fechadespliegue=NOW()"
365                " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
366                idi, idi, ido, dsk, par);
367        if (!result) {
368                dbi_conn_error(dbi->conn, &msglog);
369                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
370                       __func__, __LINE__, msglog);
371                return false;
372        }
373        dbi_result_free(result);
374
375        return true;
376}
377
378// ________________________________________________________________________________________________________
379// Función: actualizaHardware
380//
381//              Descripción:
382//                      Actualiza la base de datos con la configuracion hardware del cliente
383//              Parámetros:
384//                      - db: Objeto base de datos (ya operativo)
385//                      - tbl: Objeto tabla
386//                      - hrd: cadena con el inventario hardware
387//                      - ido: Identificador del ordenador
388//                      - npc: Nombre del ordenador
389//                      - idc: Identificador del centro o Unidad organizativa
390// ________________________________________________________________________________________________________
391//
392bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc,
393                       char *idc)
394{
395        const char *msglog;
396        int idtipohardware, idperfilhard;
397        int lon, i, j, aux;
398        bool retval;
399        char *whard;
400        int tbidhardware[MAXHARDWARE];
401        char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares;
402        dbi_result result;
403
404        /* Toma Centro (Unidad Organizativa) */
405        result = dbi_conn_queryf(dbi->conn,
406                                 "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s",
407                                 ido);
408        if (!result) {
409                dbi_conn_error(dbi->conn, &msglog);
410                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
411                       __func__, __LINE__, msglog);
412                return false;
413        }
414        if (!dbi_result_next_row(result)) {
415                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
416                       __func__, __LINE__);
417                dbi_result_free(result);
418                return false;
419        }
420        idperfilhard = dbi_result_get_uint(result, "idperfilhard");
421        dbi_result_free(result);
422
423        whard=escaparCadena(hrd); // Codificar comillas simples
424        if(!whard)
425                return false;
426        /* Recorre componentes hardware*/
427        lon = splitCadena(tbHardware, whard, '\n');
428        if (lon > MAXHARDWARE)
429                lon = MAXHARDWARE; // Limita el número de componentes hardware
430        /*
431         for (i=0;i<lon;i++){
432         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
433         RegistraLog(msglog,false);
434         }
435         */
436        for (i = 0; i < lon; i++) {
437                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
438                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
439                //RegistraLog(msglog,false);
440                //sprintf(msglog,"valor: %s",dualHardware[1]);
441                //RegistraLog(msglog,false);
442                result = dbi_conn_queryf(dbi->conn,
443                                         "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
444                                         dualHardware[0]);
445                if (!result) {
446                        dbi_conn_error(dbi->conn, &msglog);
447                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
448                               __func__, __LINE__, msglog);
449                        return false;
450                }
451                if (!dbi_result_next_row(result)) { //  Tipo de Hardware NO existente
452                        dbi_result_free(result);
453                        return false;
454                } else { //  Tipo de Hardware Existe
455                        idtipohardware = dbi_result_get_uint(result, "idtipohardware");
456                        dbi_result_free(result);
457
458                        result = dbi_conn_queryf(dbi->conn,
459                                                 "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
460                                                 idtipohardware, dualHardware[1]);
461
462                        if (!result) {
463                                dbi_conn_error(dbi->conn, &msglog);
464                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
465                                       __func__, __LINE__, msglog);
466                                return false;
467                        }
468
469                        if (!dbi_result_next_row(result)) { //  Hardware NO existente
470                                dbi_result_free(result);
471                                result = dbi_conn_queryf(dbi->conn,
472                                                        "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
473                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
474                                                dualHardware[1], idc);
475                                if (!result) {
476                                        dbi_conn_error(dbi->conn, &msglog);
477                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
478                                               __func__, __LINE__, msglog);
479                                        return false;
480                                }
481
482                                // Recupera el identificador del hardware
483                                tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
484                        } else {
485                                tbidhardware[i] = dbi_result_get_uint(result, "idhardware");
486                        }
487                        dbi_result_free(result);
488                }
489        }
490        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
491
492        for (i = 0; i < lon - 1; i++) {
493                for (j = i + 1; j < lon; j++) {
494                        if (tbidhardware[i] > tbidhardware[j]) {
495                                aux = tbidhardware[i];
496                                tbidhardware[i] = tbidhardware[j];
497                                tbidhardware[j] = aux;
498                        }
499                }
500        }
501        /* Crea cadena de identificadores de componentes hardware separados por coma */
502        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
503        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
504        idhardwares = calloc(1, sizeof(aux) * lon + lon);
505        if (idhardwares == NULL) {
506                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
507                return false;
508        }
509        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
510        for (i = 1; i < lon; i++)
511                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
512
513        if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares,
514                        npc, tbidhardware, lon)) {
515                syslog(LOG_ERR, "Problem updating client hardware\n");
516                retval=false;
517        } else {
518                retval=true;
519        }
520        free(whard);
521        free(idhardwares);
522
523        return (retval);
524}
525// ________________________________________________________________________________________________________
526// Función: cuestionPerfilHardware
527//
528//              Descripción:
529//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
530//              Parámetros:
531//                      - db: Objeto base de datos (ya operativo)
532//                      - tbl: Objeto tabla
533//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
534//                      - ido: Identificador del ordenador
535//                      - tbidhardware: Identificador del tipo de hardware
536//                      - con: Número de componentes detectados para configurar un el perfil hardware
537//                      - npc: Nombre del cliente
538// ________________________________________________________________________________________________________
539bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido,
540                int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
541                int lon)
542{
543        const char *msglog;
544        dbi_result result;
545        int i;
546        int nwidperfilhard;
547
548        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
549        result = dbi_conn_queryf(dbi->conn,
550                "SELECT idperfilhard FROM"
551                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
552                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
553                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
554                " FROM  perfileshard_hardwares"
555                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
556                " WHERE idhardwares LIKE '%s'", idhardwares);
557
558        if (!result) {
559                dbi_conn_error(dbi->conn, &msglog);
560                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
561                       __func__, __LINE__, msglog);
562                return false;
563        }
564        if (!dbi_result_next_row(result)) {
565                // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
566                dbi_result_free(result);
567                result = dbi_conn_queryf(dbi->conn,
568                                "INSERT perfileshard  (descripcion,idcentro,grupoid)"
569                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
570                if (!result) {
571                        dbi_conn_error(dbi->conn, &msglog);
572                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
573                               __func__, __LINE__, msglog);
574                        return false;
575                }
576                dbi_result_free(result);
577
578                // Recupera el identificador del nuevo perfil hardware
579                nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL);
580
581                // Crea la relación entre perfiles y componenetes hardware
582                for (i = 0; i < lon; i++) {
583                        result = dbi_conn_queryf(dbi->conn,
584                                        "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
585                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
586                        if (!result) {
587                                dbi_conn_error(dbi->conn, &msglog);
588                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
589                                       __func__, __LINE__, msglog);
590                                return false;
591                        }
592                        dbi_result_free(result);
593                }
594        } else { // Existe un perfil con todos esos componentes
595                nwidperfilhard = dbi_result_get_uint(result, "idperfilhard");
596                dbi_result_free(result);
597        }
598        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
599                // Actualiza el identificador del perfil hardware del ordenador
600                result = dbi_conn_queryf(dbi->conn,
601                        "UPDATE ordenadores SET idperfilhard=%d"
602                        " WHERE idordenador=%s", nwidperfilhard, ido);
603                if (!result) {
604                        dbi_conn_error(dbi->conn, &msglog);
605                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
606                               __func__, __LINE__, msglog);
607                        return false;
608                }
609                dbi_result_free(result);
610        }
611        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
612        result = dbi_conn_queryf(dbi->conn,
613                "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
614                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
615                " (SELECT DISTINCT idperfilhard from ordenadores))");
616        if (!result) {
617                dbi_conn_error(dbi->conn, &msglog);
618                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
619                       __func__, __LINE__, msglog);
620                return false;
621        }
622        dbi_result_free(result);
623
624        /* Eliminar Perfiles hardware que quedan húerfanos */
625        result = dbi_conn_queryf(dbi->conn,
626                        "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
627                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
628        if (!result) {
629                dbi_conn_error(dbi->conn, &msglog);
630                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
631                       __func__, __LINE__, msglog);
632                return false;
633        }
634        dbi_result_free(result);
635
636        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
637        result = dbi_conn_queryf(dbi->conn,
638                        "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
639                        " (SELECT idperfilhard FROM perfileshard)");
640        if (!result) {
641                dbi_conn_error(dbi->conn, &msglog);
642                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
643                       __func__, __LINE__, msglog);
644                return false;
645        }
646        dbi_result_free(result);
647
648        return true;
649}
650// ________________________________________________________________________________________________________
651// Función: actualizaSoftware
652//
653//      Descripción:
654//              Actualiza la base de datos con la configuración software del cliente
655//      Parámetros:
656//              - db: Objeto base de datos (ya operativo)
657//              - tbl: Objeto tabla
658//              - sft: cadena con el inventario software
659//              - par: Número de la partición
660//              - ido: Identificador del ordenador del cliente en la tabla
661//              - npc: Nombre del ordenador
662//              - idc: Identificador del centro o Unidad organizativa
663//      Devuelve:
664//              true: Si el proceso es correcto
665//              false: En caso de ocurrir algún error
666//
667//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
668// ________________________________________________________________________________________________________
669bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido,
670                       char *npc, char *idc)
671{
672        int i, j, lon, aux, idperfilsoft, idnombreso;
673        bool retval;
674        char *wsft;
675        int tbidsoftware[MAXSOFTWARE];
676        char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares;
677        const char *msglog;
678        dbi_result result;
679
680        /* Toma Centro (Unidad Organizativa) y perfil software */
681        result = dbi_conn_queryf(dbi->conn,
682                "SELECT idperfilsoft,numpar"
683                " FROM ordenadores_particiones"
684                " WHERE idordenador=%s", ido);
685        if (!result) {
686                dbi_conn_error(dbi->conn, &msglog);
687                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
688                       __func__, __LINE__, msglog);
689                return false;
690        }
691        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
692        while (dbi_result_next_row(result)) {
693                aux = dbi_result_get_uint(result, "numpar");
694                if (aux == atoi(par)) { // Se encuentra la partición
695                        idperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
696                        break;
697                }
698        }
699        dbi_result_free(result);
700        wsft=escaparCadena(sft); // Codificar comillas simples
701        if(!wsft)
702                return false;
703
704        /* Recorre componentes software*/
705        lon = splitCadena(tbSoftware, wsft, '\n');
706
707        if (lon == 0)
708                return true; // No hay lineas que procesar
709        if (lon > MAXSOFTWARE)
710                lon = MAXSOFTWARE; // Limita el número de componentes software
711
712        idnombreso = 0;
713        for (i = 0; i < lon; i++) {
714                // Primera línea es el sistema operativo: se obtiene identificador
715                if (i == 0) {
716                        idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
717                        continue;
718                }
719
720                result = dbi_conn_queryf(dbi->conn,
721                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
722                                rTrim(tbSoftware[i]));
723                if (!result) {
724                        dbi_conn_error(dbi->conn, &msglog);
725                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
726                               __func__, __LINE__, msglog);
727                        return false;
728                }
729
730                if (!dbi_result_next_row(result)) {
731                        dbi_result_free(result);
732                        result = dbi_conn_queryf(dbi->conn,
733                                                "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
734                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
735                        if (!result) { // Error al insertar
736                                dbi_conn_error(dbi->conn, &msglog);
737                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
738                                       __func__, __LINE__, msglog);
739                                return false;
740                        }
741
742                        // Recupera el identificador del software
743                        tbidsoftware[i - 1] = dbi_conn_sequence_last(dbi->conn, NULL);
744                } else {
745                        tbidsoftware[i - 1] = dbi_result_get_uint(result, "idsoftware");
746                }
747                dbi_result_free(result);
748        }
749        lon--;
750
751        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
752
753        for (i = 0; i < lon - 1; i++) {
754                for (j = i + 1; j < lon; j++) {
755                        if (tbidsoftware[i] > tbidsoftware[j]) {
756                                aux = tbidsoftware[i];
757                                tbidsoftware[i] = tbidsoftware[j];
758                                tbidsoftware[j] = aux;
759                        }
760                }
761        }
762        /* Crea cadena de identificadores de componentes software separados por coma */
763        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
764        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
765        idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon);
766        if (idsoftwares == NULL) {
767                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
768                return false;
769        }
770        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
771        for (i = 1; i < lon; i++)
772                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
773
774        // Comprueba existencia de perfil software y actualización de éste para el ordenador
775        if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares,
776                        npc, par, tbidsoftware, lon)) {
777                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
778                       __func__, __LINE__, msglog);
779                retval=false;
780        } else {
781                retval=true;
782        }
783        free(wsft);
784        free(idsoftwares);
785
786        return retval;
787}
788// ________________________________________________________________________________________________________
789// Función: CuestionPerfilSoftware
790//
791//      Parámetros:
792//              - db: Objeto base de datos (ya operativo)
793//              - tbl: Objeto tabla
794//              - idcentro: Identificador del centro en la tabla
795//              - ido: Identificador del ordenador del cliente en la tabla
796//              - idnombreso: Identificador del sistema operativo
797//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
798//              - npc: Nombre del ordenador del cliente
799//              - particion: Número de la partición
800//              - tbidsoftware: Array con los identificadores de componentes software
801//              - lon: Número de componentes
802//      Devuelve:
803//              true: Si el proceso es correcto
804//              false: En caso de ocurrir algún error
805//
806//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
807//_________________________________________________________________________________________________________
808bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
809                            int idperfilsoftware, int idnombreso,
810                            char *idsoftwares, char *npc, char *par,
811                            int *tbidsoftware, int lon)
812{
813        int i, nwidperfilsoft;
814        const char *msglog;
815        dbi_result result;
816
817        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
818        result = dbi_conn_queryf(dbi->conn,
819                "SELECT idperfilsoft FROM"
820                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
821                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
822                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
823                " FROM  perfilessoft_softwares"
824                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
825                " WHERE idsoftwares LIKE '%s'", idsoftwares);
826
827        if (!result) {
828                dbi_conn_error(dbi->conn, &msglog);
829                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
830                       __func__, __LINE__, msglog);
831                return false;
832        }
833        if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea
834                dbi_result_free(result);
835                result = dbi_conn_queryf(dbi->conn,
836                                "INSERT perfilessoft  (descripcion, idcentro, grupoid, idnombreso)"
837                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
838                if (!result) {
839                        dbi_conn_error(dbi->conn, &msglog);
840                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
841                               __func__, __LINE__, msglog);
842                        return false;
843                }
844
845                dbi_result_free(result);
846                // Recupera el identificador del nuevo perfil software
847                nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL);
848
849                // Crea la relación entre perfiles y componenetes software
850                for (i = 0; i < lon; i++) {
851                        result = dbi_conn_queryf(dbi->conn,
852                                                "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
853                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
854                        if (!result) {
855                                dbi_conn_error(dbi->conn, &msglog);
856                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
857                                       __func__, __LINE__, msglog);
858                                return false;
859                        }
860                        dbi_result_free(result);
861                }
862        } else { // Existe un perfil con todos esos componentes
863                nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
864                dbi_result_free(result);
865        }
866
867        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
868                // Actualiza el identificador del perfil software del ordenador
869                result = dbi_conn_queryf(dbi->conn,
870                                "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
871                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
872                if (!result) { // Error al insertar
873                        dbi_conn_error(dbi->conn, &msglog);
874                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
875                               __func__, __LINE__, msglog);
876                        return false;
877                }
878                dbi_result_free(result);
879        }
880
881        /* DEPURACIÓN DE PERFILES SOFTWARE */
882
883        /* Eliminar Perfiles software que quedan húerfanos */
884        result = dbi_conn_queryf(dbi->conn,
885                "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
886                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
887                " AND  idperfilsoft NOT IN"\
888                " (SELECT DISTINCT idperfilsoft from imagenes)");
889        if (!result) {
890                dbi_conn_error(dbi->conn, &msglog);
891                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
892                       __func__, __LINE__, msglog);
893                return false;
894        }
895        dbi_result_free(result),
896
897        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
898        result = dbi_conn_queryf(dbi->conn,
899                        "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
900                        " (SELECT idperfilsoft from perfilessoft)");
901        if (!result) {
902                dbi_conn_error(dbi->conn, &msglog);
903                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
904                       __func__, __LINE__, msglog);
905                return false;
906        }
907        dbi_result_free(result);
908
909        return true;
910}
Note: See TracBrowser for help on using the repository browser.