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

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

#971 linkage error after split

/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmServer.h:25: multiple definition of `servidoradm'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmServer.h:25: first defined here
/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmServer.h:26: multiple definition of `puerto'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmServer.h:26: first defined here
/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmServer.h:35: multiple definition of `tbsockets'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmServer.h:35: first defined here
/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmLib.h:81: multiple definition of `ndebug'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmLib.h:81: first defined here
/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmLib.h:80: multiple definition of `szPathFileLog'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmLib.h:80: first defined here
/usr/bin/ld: src/cfg.o:/home/opengnsys/ogServer/src/ogAdmLib.h:80: multiple definition of `szPathFileCfg'; src/ogAdmServer.o:/home/javi/trabajo/soleta/opengnsys/ogServer/src/ogAdmLib.h:80: first defined here

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