source: ogServer-Git/src/ogAdmServer.c @ 41ac15d

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

#915 Remove useless WoL shim code

Levanta() is not required, iterate over the array of IP address and make
direct calls to WakeUp?().

This is also implicitly fixing up a memleak in og_cmd_wol().

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