source: ogServer-Git/src/ogAdmServer.c @ 7d74d42

Last change on this file since 7d74d42 was 746166e, checked in by OpenGnSys Support Team <soporte-og@…>, 3 years ago

#971 Remove sql bottleneck when removing software profiles

Several universities have reported that creating a software profile
hangs the machine running the ogServer for a while, sometimes up to
minutes.

Legacy SQL code is producing said bottleneck, responsible for pruning a
intermediate table between "perfilessoft" and "softwares". There is
redundant code, "perfilssoft" should be pruned first, speeding up the
later task of pruning the intermediate table "perfilessoft_softwares"

There is no need to execute:

DELETE FROM perfilessoft_softwares
WHERE idperfilsoft IN (

SELECT idperfilsoft
FROM perfilessoft
WHERE idperfilsoft NOT IN (

SELECT DISTINCT idperfilsoft
from ordenadores_particiones)
AND idperfilsoft NOT IN (

SELECT DISTINCT idperfilsoft from imagenes))

When afterwards "perfilessoft" is going to be pruned and
"perfilessoft_softwares" pruned again:

DELETE FROM perfilessoft WHERE idperfilsoft NOT IN

(SELECT DISTINCT idperfilsoft from ordenadores_particiones)
AND idperfilsoft NOT IN
(SELECT DISTINCT idperfilsoft from imagenes)

DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN

(SELECT idperfilsoft from perfilessoft)

The two latter commands suffice.

This should not happen when using a relational database supporting
foreign keys and ON DELETE CASCADE, like innoDB, which will be adopted
soon.

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