source: ogServer-Git/sources/ogAdmServer.c @ 8215e0c

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

#988 add json configuration file

New configuration file at /opt/opengnsys/cfg/ogserver.json

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