source: ogServer-Git/src/ogAdmServer.c @ 0631b0e

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

#988 Add DB port option to ogserver.json config file

This patch provides functionality to select a database port. It also adds a
default IP for the database.

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