source: ogServer-Git/src/ogAdmServer.c @ 060e31c

Last change on this file since 060e31c was 060e31c, checked in by OpenGnSys Support Team <soporte-og@…>, 4 years ago

#990 add wol_socket_open()

Add wol_socket_open() to initialize the WoL socket

  • Property mode set to 100644
File size: 41.5 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
26char usuario[4096]; // Usuario de acceso a la base de datos
27char pasguor[4096]; // Password del usuario
28char datasource[4096]; // Dirección IP del gestor de base de datos
29char catalog[4096]; // Nombre de la base de datos
30char interface[4096]; // Interface name
31char auth_token[4096]; // API token
32char servidoradm[4096]; // Dirección IP del servidor de administración
33char puerto[4096];    // Puerto de comunicación
34char db_port[4096];
35
36SOCKETCL tbsockets[MAXIMOS_CLIENTES];
37
38struct og_dbi_config dbi_config = {
39        .user           = usuario,
40        .passwd         = pasguor,
41        .host           = datasource,
42        .port           = db_port,
43        .database       = catalog,
44};
45
46//________________________________________________________________________________________________________
47//      Función: tomaConfiguracion
48//
49//      Descripción:
50//              Lee el fichero de configuración del servicio
51//      Parámetros:
52//              filecfg : Ruta completa al fichero de configuración
53//      Devuelve:
54//              true: Si el proceso es correcto
55//              false: En caso de ocurrir algún error
56//________________________________________________________________________________________________________
57bool tomaConfiguracion(const char *filecfg)
58{
59        char buf[1024], *line;
60        char *key, *value;
61        FILE *fcfg;
62
63        if (filecfg == NULL || strlen(filecfg) == 0) {
64                syslog(LOG_ERR, "No configuration file has been specified\n");
65                return false;
66        }
67
68        fcfg = fopen(filecfg, "rt");
69        if (fcfg == NULL) {
70                syslog(LOG_ERR, "Cannot open configuration file `%s'\n",
71                       filecfg);
72                return false;
73        }
74
75        servidoradm[0] = '\0'; //inicializar variables globales
76
77        line = fgets(buf, sizeof(buf), fcfg);
78        while (line != NULL) {
79                const char *delim = "=";
80
81                line[strlen(line) - 1] = '\0';
82
83                key = strtok(line, delim);
84                value = strtok(NULL, delim);
85
86                if (!strcmp(str_toupper(key), "SERVIDORADM"))
87                        snprintf(servidoradm, sizeof(servidoradm), "%s", value);
88                else if (!strcmp(str_toupper(key), "PUERTO"))
89                        snprintf(puerto, sizeof(puerto), "%s", value);
90                else if (!strcmp(str_toupper(key), "USUARIO"))
91                        snprintf(usuario, sizeof(usuario), "%s", value);
92                else if (!strcmp(str_toupper(key), "PASSWORD"))
93                        snprintf(pasguor, sizeof(pasguor), "%s", value);
94                else if (!strcmp(str_toupper(key), "DATASOURCE"))
95                        snprintf(datasource, sizeof(datasource), "%s", value);
96                else if (!strcmp(str_toupper(key), "CATALOG"))
97                        snprintf(catalog, sizeof(catalog), "%s", value);
98                else if (!strcmp(str_toupper(key), "INTERFACE"))
99                        snprintf(interface, sizeof(interface), "%s", value);
100                else if (!strcmp(str_toupper(key), "APITOKEN"))
101                        snprintf(auth_token, sizeof(auth_token), "%s", value);
102
103                line = fgets(buf, sizeof(buf), fcfg);
104        }
105
106        /* Default value to preserve legacy config file support */
107        snprintf(db_port, sizeof(db_port), "3306");
108
109        fclose(fcfg);
110
111        if (!servidoradm[0]) {
112                syslog(LOG_ERR, "Missing SERVIDORADM in configuration file\n");
113                return false;
114        }
115        if (!puerto[0]) {
116                syslog(LOG_ERR, "Missing PUERTO in configuration file\n");
117                return false;
118        }
119        if (!usuario[0]) {
120                syslog(LOG_ERR, "Missing USUARIO in configuration file\n");
121                return false;
122        }
123        if (!pasguor[0]) {
124                syslog(LOG_ERR, "Missing PASSWORD in configuration file\n");
125                return false;
126        }
127        if (!datasource[0]) {
128                syslog(LOG_ERR, "Missing DATASOURCE in configuration file\n");
129                return false;
130        }
131        if (!catalog[0]) {
132                syslog(LOG_ERR, "Missing CATALOG in configuration file\n");
133                return false;
134        }
135        if (!interface[0])
136                syslog(LOG_ERR, "Missing INTERFACE in configuration file\n");
137
138        return true;
139}
140
141#define OG_CMD_MAXLEN           64
142
143// ________________________________________________________________________________________________________
144// Función: clienteDisponible
145//
146//      Descripción:
147//              Comprueba la disponibilidad del cliente para recibir comandos interactivos
148//      Parametros:
149//              - ip : La ip del cliente a buscar
150//              - idx: (Salida)  Indice que ocupa el cliente, de estar ya registrado
151//      Devuelve:
152//              true: Si el cliente está disponible
153//              false: En caso contrario
154// ________________________________________________________________________________________________________
155bool clienteDisponible(char *ip, int* idx)
156{
157        int estado;
158
159        if (clienteExistente(ip, idx)) {
160                estado = strcmp(tbsockets[*idx].estado, CLIENTE_OCUPADO); // Cliente ocupado
161                if (estado == 0)
162                        return false;
163
164                estado = strcmp(tbsockets[*idx].estado, CLIENTE_APAGADO); // Cliente apagado
165                if (estado == 0)
166                        return false;
167
168                estado = strcmp(tbsockets[*idx].estado, CLIENTE_INICIANDO); // Cliente en proceso de inclusión
169                if (estado == 0)
170                        return false;
171
172                return true; // En caso contrario el cliente está disponible
173        }
174        return false; // Cliente no está registrado en el sistema
175}
176// ________________________________________________________________________________________________________
177// Función: clienteExistente
178//
179//      Descripción:
180//              Comprueba si el cliente está registrado en la tabla de socket del sistema
181//      Parametros:
182//              - ip : La ip del cliente a buscar
183//              - idx:(Salida)  Indice que ocupa el cliente, de estar ya registrado
184//      Devuelve:
185//              true: Si el cliente está registrado
186//              false: En caso contrario
187// ________________________________________________________________________________________________________
188bool clienteExistente(char *ip, int* idx)
189{
190        int i;
191        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
192                if (contieneIP(ip, tbsockets[i].ip)) { // Si existe la IP en la cadena
193                        *idx = i;
194                        return true;
195                }
196        }
197        return false;
198}
199// ________________________________________________________________________________________________________
200// Función: actualizaConfiguracion
201//
202//      Descripción:
203//              Esta función actualiza la base de datos con la configuracion de particiones de un cliente
204//      Parámetros:
205//              - db: Objeto base de datos (ya operativo)
206//              - tbl: Objeto tabla
207//              - cfg: cadena con una Configuración
208//              - ido: Identificador del ordenador cliente
209//      Devuelve:
210//              true: Si el proceso es correcto
211//              false: En caso de ocurrir algún error
212//      Especificaciones:
213//              Los parametros de la configuración son:
214//                      par= Número de partición
215//                      cpt= Codigo o tipo de partición
216//                      sfi= Sistema de ficheros que está implementado en la partición
217//                      soi= Nombre del sistema de ficheros instalado en la partición
218//                      tam= Tamaño de la partición
219// ________________________________________________________________________________________________________
220bool actualizaConfiguracion(struct og_dbi *dbi, char *cfg, int ido)
221{
222        int lon, p, c,i, dato, swu, idsoi, idsfi,k;
223        char *ptrPar[MAXPAR], *ptrCfg[7], *ptrDual[2], tbPar[LONSTD];
224        char *ser, *disk, *par, *cpt, *sfi, *soi, *tam, *uso; // Parametros de configuración.
225        dbi_result result, result_update;
226        const char *msglog;
227
228        lon = 0;
229        p = splitCadena(ptrPar, cfg, '\n');
230        for (i = 0; i < p; i++) {
231                c = splitCadena(ptrCfg, ptrPar[i], '\t');
232
233                // Si la 1ª línea solo incluye el número de serie del equipo; actualizar BD.
234                if (i == 0 && c == 1) {
235                        splitCadena(ptrDual, ptrCfg[0], '=');
236                        ser = ptrDual[1];
237                        if (strlen(ser) > 0) {
238                                // Solo actualizar si número de serie no existía.
239                                result = dbi_conn_queryf(dbi->conn,
240                                                "UPDATE ordenadores SET numserie='%s'"
241                                                " WHERE idordenador=%d AND numserie IS NULL",
242                                                ser, ido);
243                                if (!result) {
244                                        dbi_conn_error(dbi->conn, &msglog);
245                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
246                                               __func__, __LINE__, msglog);
247                                        return false;
248                                }
249                                dbi_result_free(result);
250                        }
251                        continue;
252                }
253
254                // Distribución de particionado.
255                disk = par = cpt = sfi = soi = tam = uso = NULL;
256
257                splitCadena(ptrDual, ptrCfg[0], '=');
258                disk = ptrDual[1]; // Número de disco
259
260                splitCadena(ptrDual, ptrCfg[1], '=');
261                par = ptrDual[1]; // Número de partición
262
263                k=splitCadena(ptrDual, ptrCfg[2], '=');
264                if(k==2){
265                        cpt = ptrDual[1]; // Código de partición
266                }else{
267                        cpt = (char*)"0";
268                }
269
270                k=splitCadena(ptrDual, ptrCfg[3], '=');
271                if(k==2){
272                        sfi = ptrDual[1]; // Sistema de ficheros
273                        /* Comprueba existencia del s0xistema de ficheros instalado */
274                        idsfi = checkDato(dbi, sfi, "sistemasficheros", "descripcion","idsistemafichero");
275                }
276                else
277                        idsfi=0;
278
279                k=splitCadena(ptrDual, ptrCfg[4], '=');
280                if(k==2){ // Sistema operativo detecdtado
281                        soi = ptrDual[1]; // Nombre del S.O. instalado
282                        /* Comprueba existencia del sistema operativo instalado */
283                        idsoi = checkDato(dbi, soi, "nombresos", "nombreso", "idnombreso");
284                }
285                else
286                        idsoi=0;
287
288                splitCadena(ptrDual, ptrCfg[5], '=');
289                tam = ptrDual[1]; // Tamaño de la partición
290
291                splitCadena(ptrDual, ptrCfg[6], '=');
292                uso = ptrDual[1]; // Porcentaje de uso del S.F.
293
294                lon += sprintf(tbPar + lon, "(%s, %s),", disk, par);
295
296                result = dbi_conn_queryf(dbi->conn,
297                                "SELECT numdisk, numpar, tamano, uso, idsistemafichero, idnombreso"
298                                "  FROM ordenadores_particiones"
299                                " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
300                                ido, disk, par);
301                if (!result) {
302                        dbi_conn_error(dbi->conn, &msglog);
303                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
304                               __func__, __LINE__, msglog);
305                        return false;
306                }
307                if (!dbi_result_next_row(result)) {
308                        result_update = dbi_conn_queryf(dbi->conn,
309                                        "INSERT INTO ordenadores_particiones(idordenador,numdisk,numpar,codpar,tamano,uso,idsistemafichero,idnombreso,idimagen)"
310                                        " VALUES(%d,%s,%s,0x%s,%s,%s,%d,%d,0)",
311                                        ido, disk, par, cpt, tam, uso, idsfi, idsoi);
312                        if (!result_update) {
313                                dbi_conn_error(dbi->conn, &msglog);
314                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
315                                       __func__, __LINE__, msglog);
316                                return false;
317                        }
318                        dbi_result_free(result_update);
319
320                } else { // Existe el registro
321                        swu = true; // Se supone que algún dato ha cambiado
322
323                        dato = dbi_result_get_uint(result, "tamano");
324                        if (atoi(tam) == dato) {// Parámetro tamaño igual al almacenado
325                                dato = dbi_result_get_uint(result, "idsistemafichero");
326                                if (idsfi == dato) {// Parámetro sistema de fichero igual al almacenado
327                                        dato = dbi_result_get_uint(result, "idnombreso");
328                                        if (idsoi == dato) {// Parámetro sistema de fichero distinto al almacenado
329                                                swu = false; // Todos los parámetros de la partición son iguales, no se actualiza
330                                        }
331                                }
332                        }
333                        if (swu) { // Hay que actualizar los parámetros de la partición
334                                result_update = dbi_conn_queryf(dbi->conn,
335                                        "UPDATE ordenadores_particiones SET "
336                                        " codpar=0x%s,"
337                                        " tamano=%s,"
338                                        " uso=%s,"
339                                        " idsistemafichero=%d,"
340                                        " idnombreso=%d,"
341                                        " idimagen=0,"
342                                        " idperfilsoft=0,"
343                                        " fechadespliegue=NULL"
344                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
345                                        cpt, tam, uso, idsfi, idsoi, ido, disk, par);
346                        } else {  // Actualizar porcentaje de uso.
347                                result_update = dbi_conn_queryf(dbi->conn,
348                                        "UPDATE ordenadores_particiones SET "
349                                        " codpar=0x%s,"
350                                        " uso=%s"
351                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
352                                        cpt, uso, ido, disk, par);
353                        }
354                        if (!result_update) {
355                                dbi_conn_error(dbi->conn, &msglog);
356                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
357                                       __func__, __LINE__, msglog);
358                                return false;
359                        }
360
361                        dbi_result_free(result_update);
362                }
363                dbi_result_free(result);
364        }
365        lon += sprintf(tbPar + lon, "(0,0)");
366        // Eliminar particiones almacenadas que ya no existen
367        result_update = dbi_conn_queryf(dbi->conn,
368                "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)",
369                        ido, tbPar);
370        if (!result_update) {
371                dbi_conn_error(dbi->conn, &msglog);
372                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
373                       __func__, __LINE__, msglog);
374                return false;
375        }
376        dbi_result_free(result_update);
377
378        return true;
379}
380// ________________________________________________________________________________________________________
381// Función: checkDato
382//
383//      Descripción:
384//               Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en
385//              cualquier caso el identificador del registro existenet o del insertado
386//      Parámetros:
387//              - db: Objeto base de datos (ya operativo)
388//              - tbl: Objeto tabla
389//              - dato: Dato
390//              - tabla: Nombre de la tabla
391//              - nomdato: Nombre del dato en la tabla
392//              - nomidentificador: Nombre del identificador en la tabla
393//      Devuelve:
394//              El identificador del registro existente o el del insertado
395//
396//      Especificaciones:
397//              En caso de producirse algún error se devuelve el valor 0
398// ________________________________________________________________________________________________________
399
400int checkDato(struct og_dbi *dbi, char *dato, const char *tabla,
401                     const char *nomdato, const char *nomidentificador)
402{
403        const char *msglog;
404        int identificador;
405        dbi_result result;
406
407        if (strlen(dato) == 0)
408                return (0); // EL dato no tiene valor
409        result = dbi_conn_queryf(dbi->conn,
410                        "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador,
411                        tabla, nomdato, dato);
412
413        // Ejecuta consulta
414        if (!result) {
415                dbi_conn_error(dbi->conn, &msglog);
416                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
417                       __func__, __LINE__, msglog);
418                return (0);
419        }
420        if (!dbi_result_next_row(result)) { //  Software NO existente
421                dbi_result_free(result);
422
423                result = dbi_conn_queryf(dbi->conn,
424                                "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato);
425                if (!result) {
426                        dbi_conn_error(dbi->conn, &msglog);
427                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
428                               __func__, __LINE__, msglog);
429                        return (0);
430                }
431                // Recupera el identificador del software
432                identificador = dbi_conn_sequence_last(dbi->conn, NULL);
433        } else {
434                identificador = dbi_result_get_uint(result, nomidentificador);
435        }
436        dbi_result_free(result);
437
438        return (identificador);
439}
440
441// ________________________________________________________________________________________________________
442// Función: Levanta
443//
444//      Descripción:
445//              Enciende ordenadores a través de la red cuyas macs se pasan como parámetro
446//      Parámetros:
447//              - iph: Cadena de direcciones ip separadas por ";"
448//              - mac: Cadena de direcciones mac separadas por ";"
449//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
450//      Devuelve:
451//              true: Si el proceso es correcto
452//              false: En caso de ocurrir algún error
453// ________________________________________________________________________________________________________
454
455bool Levanta(char *ptrIP[], char *ptrMacs[], char *ptrNetmasks[], int lon,
456             char *mar)
457{
458        int i, s;
459
460        s = wol_socket_open();
461        if (s < 0)
462                return false;
463
464        for (i = 0; i < lon; i++) {
465                if (!WakeUp(s, ptrIP[i], ptrMacs[i], ptrNetmasks[i], mar)) {
466                        syslog(LOG_ERR, "problem sending magic packet\n");
467                        close(s);
468                        return false;
469                }
470        }
471        close(s);
472        return true;
473}
474
475enum wol_delivery_type {
476        OG_WOL_BROADCAST = 1,
477        OG_WOL_UNICAST = 2
478};
479
480//_____________________________________________________________________________________________________________
481// Función: WakeUp
482//
483//       Descripción:
484//              Enciende el ordenador cuya MAC se pasa como parámetro
485//      Parámetros:
486//              - s : Socket para enviar trama magic packet
487//              - iph : Cadena con la dirección ip
488//              - mac : Cadena con la dirección mac en formato XXXXXXXXXXXX
489//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
490//      Devuelve:
491//              true: Si el proceso es correcto
492//              false: En caso de ocurrir algún error
493//_____________________________________________________________________________________________________________
494//
495bool WakeUp(int s, char* iph, char *mac, char *netmask, char *mar)
496{
497        struct in_addr addr, netmask_addr, broadcast_addr ={};
498        unsigned int macaddr[OG_WOL_MACADDR_LEN];
499        char HDaddress_bin[OG_WOL_MACADDR_LEN];
500        struct sockaddr_in WakeUpCliente;
501        struct wol_msg Trama_WakeUp;
502        bool ret;
503        int i;
504
505        if (inet_aton(iph, &addr) < 0) {
506                syslog(LOG_ERR, "bad IP address\n");
507                return false;
508        }
509
510        if (inet_aton(netmask, &netmask_addr) < 0) {
511                syslog(LOG_ERR, "bad netmask address: %s\n", netmask);
512                return false;
513        }
514
515        broadcast_addr.s_addr = addr.s_addr | ~netmask_addr.s_addr;
516
517        for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF)
518                Trama_WakeUp.secuencia_FF[i] = 0xFF;
519
520        sscanf(mac, "%02x%02x%02x%02x%02x%02x",
521               &macaddr[0], &macaddr[1], &macaddr[2],
522               &macaddr[3], &macaddr[4], &macaddr[5]);
523
524        for (i = 0; i < 6; i++)
525                HDaddress_bin[i] = (uint8_t)macaddr[i];
526
527        for (i = 0; i < 16; i++) // Segunda secuencia de la trama Wake Up , repetir 16 veces su la MAC
528                memcpy(&Trama_WakeUp.macbin[i][0], &HDaddress_bin, 6);
529
530        /* Creación de socket del cliente que recibe la trama magic packet */
531        WakeUpCliente.sin_family = AF_INET;
532        WakeUpCliente.sin_port = htons((short) PUERTO_WAKEUP);
533
534        switch (atoi(mar)) {
535        case OG_WOL_BROADCAST:
536                ret = wake_up_broadcast(s, &WakeUpCliente, &Trama_WakeUp);
537                ret &= wake_up_send(s, &WakeUpCliente, &Trama_WakeUp,
538                                    &broadcast_addr);
539                break;
540        case OG_WOL_UNICAST:
541                ret = wake_up_send(s, &WakeUpCliente, &Trama_WakeUp, &addr);
542                break;
543        default:
544                syslog(LOG_ERR, "unknown wol type\n");
545                ret = false;
546                break;
547        }
548        return ret;
549}
550
551// ________________________________________________________________________________________________________
552// Función: actualizaCreacionImagen
553//
554//      Descripción:
555//              Esta función actualiza la base de datos con el resultado de la creación de una imagen
556//      Parámetros:
557//              - db: Objeto base de datos (ya operativo)
558//              - tbl: Objeto tabla
559//              - idi: Identificador de la imagen
560//              - dsk: Disco de donde se creó
561//              - par: Partición de donde se creó
562//              - cpt: Código de partición
563//              - ipr: Ip del repositorio
564//              - ido: Identificador del ordenador modelo
565//      Devuelve:
566//              true: Si el proceso es correcto
567//              false: En caso de ocurrir algún error
568// ________________________________________________________________________________________________________
569bool actualizaCreacionImagen(struct og_dbi *dbi, char *idi, char *dsk,
570                             char *par, char *cpt, char *ipr, char *ido)
571{
572        const char *msglog;
573        dbi_result result;
574        int idr,ifs;
575
576        /* Toma identificador del repositorio correspondiente al ordenador modelo */
577        result = dbi_conn_queryf(dbi->conn,
578                        "SELECT repositorios.idrepositorio"
579                        "  FROM repositorios"
580                        "  LEFT JOIN ordenadores USING (idrepositorio)"
581                        " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
582
583        if (!result) {
584                dbi_conn_error(dbi->conn, &msglog);
585                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
586                       __func__, __LINE__, msglog);
587                return false;
588        }
589        if (!dbi_result_next_row(result)) {
590                syslog(LOG_ERR,
591                       "repository does not exist in database (%s:%d)\n",
592                       __func__, __LINE__);
593                dbi_result_free(result);
594                return false;
595        }
596        idr = dbi_result_get_uint(result, "idrepositorio");
597        dbi_result_free(result);
598
599        /* Toma identificador del perfilsoftware */
600        result = dbi_conn_queryf(dbi->conn,
601                        "SELECT idperfilsoft"
602                        "  FROM ordenadores_particiones"
603                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
604
605        if (!result) {
606                dbi_conn_error(dbi->conn, &msglog);
607                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
608                       __func__, __LINE__, msglog);
609                return false;
610        }
611        if (!dbi_result_next_row(result)) {
612                syslog(LOG_ERR,
613                       "software profile does not exist in database (%s:%d)\n",
614                       __func__, __LINE__);
615                dbi_result_free(result);
616                return false;
617        }
618        ifs = dbi_result_get_uint(result, "idperfilsoft");
619        dbi_result_free(result);
620
621        /* Actualizar los datos de la imagen */
622        result = dbi_conn_queryf(dbi->conn,
623                "UPDATE imagenes"
624                "   SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
625                "       idperfilsoft=%d, idrepositorio=%d,"
626                "       fechacreacion=NOW(), revision=revision+1"
627                " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
628
629        if (!result) {
630                dbi_conn_error(dbi->conn, &msglog);
631                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
632                       __func__, __LINE__, msglog);
633                return false;
634        }
635        dbi_result_free(result);
636
637        /* Actualizar los datos en el cliente */
638        result = dbi_conn_queryf(dbi->conn,
639                "UPDATE ordenadores_particiones"
640                "   SET idimagen=%s, revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
641                "       fechadespliegue=NOW()"
642                " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
643                idi, idi, ido, dsk, par);
644        if (!result) {
645                dbi_conn_error(dbi->conn, &msglog);
646                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
647                       __func__, __LINE__, msglog);
648                return false;
649        }
650        dbi_result_free(result);
651
652        return true;
653}
654
655// ________________________________________________________________________________________________________
656// Función: actualizaRestauracionImagen
657//
658//      Descripción:
659//              Esta función actualiza la base de datos con el resultado de la restauración de una imagen
660//      Parámetros:
661//              - db: Objeto base de datos (ya operativo)
662//              - tbl: Objeto tabla
663//              - idi: Identificador de la imagen
664//              - dsk: Disco de donde se restauró
665//              - par: Partición de donde se restauró
666//              - ido: Identificador del cliente donde se restauró
667//              - ifs: Identificador del perfil software contenido      en la imagen
668//      Devuelve:
669//              true: Si el proceso es correcto
670//              false: En caso de ocurrir algún error
671// ________________________________________________________________________________________________________
672bool actualizaRestauracionImagen(struct og_dbi *dbi, char *idi,
673                                 char *dsk, char *par, char *ido, char *ifs)
674{
675        const char *msglog;
676        dbi_result result;
677
678        /* Actualizar los datos de la imagen */
679        result = dbi_conn_queryf(dbi->conn,
680                        "UPDATE ordenadores_particiones"
681                        "   SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
682                        "       revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
683                        "       idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
684                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", idi, ifs, idi, ifs, ido, dsk, par);
685
686        if (!result) {
687                dbi_conn_error(dbi->conn, &msglog);
688                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
689                       __func__, __LINE__, msglog);
690                return false;
691        }
692        dbi_result_free(result);
693
694        return true;
695}
696// ________________________________________________________________________________________________________
697// Función: actualizaHardware
698//
699//              Descripción:
700//                      Actualiza la base de datos con la configuracion hardware del cliente
701//              Parámetros:
702//                      - db: Objeto base de datos (ya operativo)
703//                      - tbl: Objeto tabla
704//                      - hrd: cadena con el inventario hardware
705//                      - ido: Identificador del ordenador
706//                      - npc: Nombre del ordenador
707//                      - idc: Identificador del centro o Unidad organizativa
708// ________________________________________________________________________________________________________
709//
710bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc,
711                       char *idc)
712{
713        const char *msglog;
714        int idtipohardware, idperfilhard;
715        int lon, i, j, aux;
716        bool retval;
717        char *whard;
718        int tbidhardware[MAXHARDWARE];
719        char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares;
720        dbi_result result;
721
722        /* Toma Centro (Unidad Organizativa) */
723        result = dbi_conn_queryf(dbi->conn,
724                                 "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s",
725                                 ido);
726        if (!result) {
727                dbi_conn_error(dbi->conn, &msglog);
728                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
729                       __func__, __LINE__, msglog);
730                return false;
731        }
732        if (!dbi_result_next_row(result)) {
733                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
734                       __func__, __LINE__);
735                dbi_result_free(result);
736                return false;
737        }
738        idperfilhard = dbi_result_get_uint(result, "idperfilhard");
739        dbi_result_free(result);
740
741        whard=escaparCadena(hrd); // Codificar comillas simples
742        if(!whard)
743                return false;
744        /* Recorre componentes hardware*/
745        lon = splitCadena(tbHardware, whard, '\n');
746        if (lon > MAXHARDWARE)
747                lon = MAXHARDWARE; // Limita el número de componentes hardware
748        /*
749         for (i=0;i<lon;i++){
750         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
751         RegistraLog(msglog,false);
752         }
753         */
754        for (i = 0; i < lon; i++) {
755                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
756                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
757                //RegistraLog(msglog,false);
758                //sprintf(msglog,"valor: %s",dualHardware[1]);
759                //RegistraLog(msglog,false);
760                result = dbi_conn_queryf(dbi->conn,
761                                         "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
762                                         dualHardware[0]);
763                if (!result) {
764                        dbi_conn_error(dbi->conn, &msglog);
765                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
766                               __func__, __LINE__, msglog);
767                        return false;
768                }
769                if (!dbi_result_next_row(result)) { //  Tipo de Hardware NO existente
770                        dbi_result_free(result);
771                        return false;
772                } else { //  Tipo de Hardware Existe
773                        idtipohardware = dbi_result_get_uint(result, "idtipohardware");
774                        dbi_result_free(result);
775
776                        result = dbi_conn_queryf(dbi->conn,
777                                                 "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
778                                                 idtipohardware, dualHardware[1]);
779
780                        if (!result) {
781                                dbi_conn_error(dbi->conn, &msglog);
782                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
783                                       __func__, __LINE__, msglog);
784                                return false;
785                        }
786
787                        if (!dbi_result_next_row(result)) { //  Hardware NO existente
788                                dbi_result_free(result);
789                                result = dbi_conn_queryf(dbi->conn,
790                                                        "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
791                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
792                                                dualHardware[1], idc);
793                                if (!result) {
794                                        dbi_conn_error(dbi->conn, &msglog);
795                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
796                                               __func__, __LINE__, msglog);
797                                        return false;
798                                }
799
800                                // Recupera el identificador del hardware
801                                tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
802                        } else {
803                                tbidhardware[i] = dbi_result_get_uint(result, "idhardware");
804                        }
805                        dbi_result_free(result);
806                }
807        }
808        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
809
810        for (i = 0; i < lon - 1; i++) {
811                for (j = i + 1; j < lon; j++) {
812                        if (tbidhardware[i] > tbidhardware[j]) {
813                                aux = tbidhardware[i];
814                                tbidhardware[i] = tbidhardware[j];
815                                tbidhardware[j] = aux;
816                        }
817                }
818        }
819        /* Crea cadena de identificadores de componentes hardware separados por coma */
820        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
821        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
822        idhardwares = calloc(1, sizeof(aux) * lon + lon);
823        if (idhardwares == NULL) {
824                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
825                return false;
826        }
827        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
828        for (i = 1; i < lon; i++)
829                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
830
831        if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares,
832                        npc, tbidhardware, lon)) {
833                syslog(LOG_ERR, "Problem updating client hardware\n");
834                retval=false;
835        } else {
836                retval=true;
837        }
838        free(whard);
839        free(idhardwares);
840
841        return (retval);
842}
843// ________________________________________________________________________________________________________
844// Función: cuestionPerfilHardware
845//
846//              Descripción:
847//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
848//              Parámetros:
849//                      - db: Objeto base de datos (ya operativo)
850//                      - tbl: Objeto tabla
851//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
852//                      - ido: Identificador del ordenador
853//                      - tbidhardware: Identificador del tipo de hardware
854//                      - con: Número de componentes detectados para configurar un el perfil hardware
855//                      - npc: Nombre del cliente
856// ________________________________________________________________________________________________________
857bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido,
858                int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
859                int lon)
860{
861        const char *msglog;
862        dbi_result result;
863        int i;
864        int nwidperfilhard;
865
866        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
867        result = dbi_conn_queryf(dbi->conn,
868                "SELECT idperfilhard FROM"
869                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
870                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
871                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
872                " FROM  perfileshard_hardwares"
873                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
874                " WHERE idhardwares LIKE '%s'", idhardwares);
875
876        if (!result) {
877                dbi_conn_error(dbi->conn, &msglog);
878                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
879                       __func__, __LINE__, msglog);
880                return false;
881        }
882        if (!dbi_result_next_row(result)) {
883                // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
884                dbi_result_free(result);
885                result = dbi_conn_queryf(dbi->conn,
886                                "INSERT perfileshard  (descripcion,idcentro,grupoid)"
887                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
888                if (!result) {
889                        dbi_conn_error(dbi->conn, &msglog);
890                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
891                               __func__, __LINE__, msglog);
892                        return false;
893                }
894                dbi_result_free(result);
895
896                // Recupera el identificador del nuevo perfil hardware
897                nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL);
898
899                // Crea la relación entre perfiles y componenetes hardware
900                for (i = 0; i < lon; i++) {
901                        result = dbi_conn_queryf(dbi->conn,
902                                        "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
903                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
904                        if (!result) {
905                                dbi_conn_error(dbi->conn, &msglog);
906                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
907                                       __func__, __LINE__, msglog);
908                                return false;
909                        }
910                        dbi_result_free(result);
911                }
912        } else { // Existe un perfil con todos esos componentes
913                nwidperfilhard = dbi_result_get_uint(result, "idperfilhard");
914                dbi_result_free(result);
915        }
916        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
917                // Actualiza el identificador del perfil hardware del ordenador
918                result = dbi_conn_queryf(dbi->conn,
919                        "UPDATE ordenadores SET idperfilhard=%d"
920                        " WHERE idordenador=%s", nwidperfilhard, ido);
921                if (!result) {
922                        dbi_conn_error(dbi->conn, &msglog);
923                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
924                               __func__, __LINE__, msglog);
925                        return false;
926                }
927                dbi_result_free(result);
928        }
929        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
930        result = dbi_conn_queryf(dbi->conn,
931                "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
932                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
933                " (SELECT DISTINCT idperfilhard from ordenadores))");
934        if (!result) {
935                dbi_conn_error(dbi->conn, &msglog);
936                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
937                       __func__, __LINE__, msglog);
938                return false;
939        }
940        dbi_result_free(result);
941
942        /* Eliminar Perfiles hardware que quedan húerfanos */
943        result = dbi_conn_queryf(dbi->conn,
944                        "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
945                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
946        if (!result) {
947                dbi_conn_error(dbi->conn, &msglog);
948                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
949                       __func__, __LINE__, msglog);
950                return false;
951        }
952        dbi_result_free(result);
953
954        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
955        result = dbi_conn_queryf(dbi->conn,
956                        "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
957                        " (SELECT idperfilhard FROM perfileshard)");
958        if (!result) {
959                dbi_conn_error(dbi->conn, &msglog);
960                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
961                       __func__, __LINE__, msglog);
962                return false;
963        }
964        dbi_result_free(result);
965
966        return true;
967}
968// ________________________________________________________________________________________________________
969// Función: actualizaSoftware
970//
971//      Descripción:
972//              Actualiza la base de datos con la configuración software del cliente
973//      Parámetros:
974//              - db: Objeto base de datos (ya operativo)
975//              - tbl: Objeto tabla
976//              - sft: cadena con el inventario software
977//              - par: Número de la partición
978//              - ido: Identificador del ordenador del cliente en la tabla
979//              - npc: Nombre del ordenador
980//              - idc: Identificador del centro o Unidad organizativa
981//      Devuelve:
982//              true: Si el proceso es correcto
983//              false: En caso de ocurrir algún error
984//
985//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
986// ________________________________________________________________________________________________________
987bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido,
988                       char *npc, char *idc)
989{
990        int i, j, lon, aux, idperfilsoft, idnombreso;
991        bool retval;
992        char *wsft;
993        int tbidsoftware[MAXSOFTWARE];
994        char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares;
995        const char *msglog;
996        dbi_result result;
997
998        /* Toma Centro (Unidad Organizativa) y perfil software */
999        result = dbi_conn_queryf(dbi->conn,
1000                "SELECT idperfilsoft,numpar"
1001                " FROM ordenadores_particiones"
1002                " WHERE idordenador=%s", ido);
1003        if (!result) {
1004                dbi_conn_error(dbi->conn, &msglog);
1005                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1006                       __func__, __LINE__, msglog);
1007                return false;
1008        }
1009        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
1010        while (dbi_result_next_row(result)) {
1011                aux = dbi_result_get_uint(result, "numpar");
1012                if (aux == atoi(par)) { // Se encuentra la partición
1013                        idperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
1014                        break;
1015                }
1016        }
1017        dbi_result_free(result);
1018        wsft=escaparCadena(sft); // Codificar comillas simples
1019        if(!wsft)
1020                return false;
1021
1022        /* Recorre componentes software*/
1023        lon = splitCadena(tbSoftware, wsft, '\n');
1024
1025        if (lon == 0)
1026                return true; // No hay lineas que procesar
1027        if (lon > MAXSOFTWARE)
1028                lon = MAXSOFTWARE; // Limita el número de componentes software
1029
1030        idnombreso = 0;
1031        for (i = 0; i < lon; i++) {
1032                // Primera línea es el sistema operativo: se obtiene identificador
1033                if (i == 0) {
1034                        idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
1035                        continue;
1036                }
1037
1038                result = dbi_conn_queryf(dbi->conn,
1039                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
1040                                rTrim(tbSoftware[i]));
1041                if (!result) {
1042                        dbi_conn_error(dbi->conn, &msglog);
1043                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1044                               __func__, __LINE__, msglog);
1045                        return false;
1046                }
1047
1048                if (!dbi_result_next_row(result)) {
1049                        dbi_result_free(result);
1050                        result = dbi_conn_queryf(dbi->conn,
1051                                                "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
1052                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
1053                        if (!result) { // Error al insertar
1054                                dbi_conn_error(dbi->conn, &msglog);
1055                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1056                                       __func__, __LINE__, msglog);
1057                                return false;
1058                        }
1059
1060                        // Recupera el identificador del software
1061                        tbidsoftware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
1062                } else {
1063                        tbidsoftware[i] = dbi_result_get_uint(result, "idsoftware");
1064                }
1065                dbi_result_free(result);
1066        }
1067
1068        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
1069
1070        for (i = 0; i < lon - 1; i++) {
1071                for (j = i + 1; j < lon; j++) {
1072                        if (tbidsoftware[i] > tbidsoftware[j]) {
1073                                aux = tbidsoftware[i];
1074                                tbidsoftware[i] = tbidsoftware[j];
1075                                tbidsoftware[j] = aux;
1076                        }
1077                }
1078        }
1079        /* Crea cadena de identificadores de componentes software separados por coma */
1080        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
1081        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
1082        idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon);
1083        if (idsoftwares == NULL) {
1084                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
1085                return false;
1086        }
1087        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
1088        for (i = 1; i < lon; i++)
1089                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
1090
1091        // Comprueba existencia de perfil software y actualización de éste para el ordenador
1092        if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares,
1093                        npc, par, tbidsoftware, lon)) {
1094                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1095                       __func__, __LINE__, msglog);
1096                retval=false;
1097        } else {
1098                retval=true;
1099        }
1100        free(wsft);
1101        free(idsoftwares);
1102
1103        return retval;
1104}
1105// ________________________________________________________________________________________________________
1106// Función: CuestionPerfilSoftware
1107//
1108//      Parámetros:
1109//              - db: Objeto base de datos (ya operativo)
1110//              - tbl: Objeto tabla
1111//              - idcentro: Identificador del centro en la tabla
1112//              - ido: Identificador del ordenador del cliente en la tabla
1113//              - idnombreso: Identificador del sistema operativo
1114//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
1115//              - npc: Nombre del ordenador del cliente
1116//              - particion: Número de la partición
1117//              - tbidsoftware: Array con los identificadores de componentes software
1118//              - lon: Número de componentes
1119//      Devuelve:
1120//              true: Si el proceso es correcto
1121//              false: En caso de ocurrir algún error
1122//
1123//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
1124//_________________________________________________________________________________________________________
1125bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
1126                            int idperfilsoftware, int idnombreso,
1127                            char *idsoftwares, char *npc, char *par,
1128                            int *tbidsoftware, int lon)
1129{
1130        int i, nwidperfilsoft;
1131        const char *msglog;
1132        dbi_result result;
1133
1134        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
1135        result = dbi_conn_queryf(dbi->conn,
1136                "SELECT idperfilsoft FROM"
1137                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
1138                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
1139                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
1140                " FROM  perfilessoft_softwares"
1141                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
1142                " WHERE idsoftwares LIKE '%s'", idsoftwares);
1143
1144        if (!result) {
1145                dbi_conn_error(dbi->conn, &msglog);
1146                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1147                       __func__, __LINE__, msglog);
1148                return false;
1149        }
1150        if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea
1151                dbi_result_free(result);
1152                result = dbi_conn_queryf(dbi->conn,
1153                                "INSERT perfilessoft  (descripcion, idcentro, grupoid, idnombreso)"
1154                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
1155                if (!result) {
1156                        dbi_conn_error(dbi->conn, &msglog);
1157                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1158                               __func__, __LINE__, msglog);
1159                        return false;
1160                }
1161
1162                dbi_result_free(result);
1163                // Recupera el identificador del nuevo perfil software
1164                nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL);
1165
1166                // Crea la relación entre perfiles y componenetes software
1167                for (i = 0; i < lon; i++) {
1168                        result = dbi_conn_queryf(dbi->conn,
1169                                                "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
1170                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
1171                        if (!result) {
1172                                dbi_conn_error(dbi->conn, &msglog);
1173                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1174                                       __func__, __LINE__, msglog);
1175                                return false;
1176                        }
1177                        dbi_result_free(result);
1178                }
1179        } else { // Existe un perfil con todos esos componentes
1180                nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
1181                dbi_result_free(result);
1182        }
1183
1184        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
1185                // Actualiza el identificador del perfil software del ordenador
1186                result = dbi_conn_queryf(dbi->conn,
1187                                "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
1188                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
1189                if (!result) { // Error al insertar
1190                        dbi_conn_error(dbi->conn, &msglog);
1191                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1192                               __func__, __LINE__, msglog);
1193                        return false;
1194                }
1195                dbi_result_free(result);
1196        }
1197
1198        /* DEPURACIÓN DE PERFILES SOFTWARE */
1199
1200         /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
1201        result = dbi_conn_queryf(dbi->conn,
1202                "DELETE FROM perfilessoft_softwares WHERE idperfilsoft IN "\
1203                " (SELECT idperfilsoft FROM perfilessoft WHERE idperfilsoft NOT IN"\
1204                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones) AND idperfilsoft NOT IN"\
1205                " (SELECT DISTINCT idperfilsoft from imagenes))");
1206        if (!result) {
1207                dbi_conn_error(dbi->conn, &msglog);
1208                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1209                       __func__, __LINE__, msglog);
1210                return false;
1211        }
1212        dbi_result_free(result),
1213        /* Eliminar Perfiles software que quedan húerfanos */
1214        result = dbi_conn_queryf(dbi->conn,
1215                "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
1216                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
1217                " AND  idperfilsoft NOT IN"\
1218                " (SELECT DISTINCT idperfilsoft from imagenes)");
1219        if (!result) {
1220                dbi_conn_error(dbi->conn, &msglog);
1221                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1222                       __func__, __LINE__, msglog);
1223                return false;
1224        }
1225        dbi_result_free(result),
1226
1227        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
1228        result = dbi_conn_queryf(dbi->conn,
1229                        "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
1230                        " (SELECT idperfilsoft from perfilessoft)");
1231        if (!result) {
1232                dbi_conn_error(dbi->conn, &msglog);
1233                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1234                       __func__, __LINE__, msglog);
1235                return false;
1236        }
1237        dbi_result_free(result);
1238
1239        return true;
1240}
Note: See TracBrowser for help on using the repository browser.