source: ogServer-Git/src/ogAdmServer.c @ 96b02b5

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

#971 split wake on lan code

Add wol.c and wol.h that implements WakeOnLan?.

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