source: ogServer-Git/src/ogAdmServer.c @ b59ff7c

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

#998 disable incremental image API

This API is not supported by ogClient yet and it uses the obsolete socket hydra API.

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