source: ogServer-Git/src/ogAdmServer.c @ 6e70916

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

#915 remove shim code to update database after image restore command

Make direct call to dbi API to update database instead.

  • Property mode set to 100644
File size: 33.3 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: actualizaHardware
456//
457//              Descripción:
458//                      Actualiza la base de datos con la configuracion hardware del cliente
459//              Parámetros:
460//                      - db: Objeto base de datos (ya operativo)
461//                      - tbl: Objeto tabla
462//                      - hrd: cadena con el inventario hardware
463//                      - ido: Identificador del ordenador
464//                      - npc: Nombre del ordenador
465//                      - idc: Identificador del centro o Unidad organizativa
466// ________________________________________________________________________________________________________
467//
468bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc,
469                       char *idc)
470{
471        const char *msglog;
472        int idtipohardware, idperfilhard;
473        int lon, i, j, aux;
474        bool retval;
475        char *whard;
476        int tbidhardware[MAXHARDWARE];
477        char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares;
478        dbi_result result;
479
480        /* Toma Centro (Unidad Organizativa) */
481        result = dbi_conn_queryf(dbi->conn,
482                                 "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s",
483                                 ido);
484        if (!result) {
485                dbi_conn_error(dbi->conn, &msglog);
486                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
487                       __func__, __LINE__, msglog);
488                return false;
489        }
490        if (!dbi_result_next_row(result)) {
491                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
492                       __func__, __LINE__);
493                dbi_result_free(result);
494                return false;
495        }
496        idperfilhard = dbi_result_get_uint(result, "idperfilhard");
497        dbi_result_free(result);
498
499        whard=escaparCadena(hrd); // Codificar comillas simples
500        if(!whard)
501                return false;
502        /* Recorre componentes hardware*/
503        lon = splitCadena(tbHardware, whard, '\n');
504        if (lon > MAXHARDWARE)
505                lon = MAXHARDWARE; // Limita el número de componentes hardware
506        /*
507         for (i=0;i<lon;i++){
508         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
509         RegistraLog(msglog,false);
510         }
511         */
512        for (i = 0; i < lon; i++) {
513                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
514                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
515                //RegistraLog(msglog,false);
516                //sprintf(msglog,"valor: %s",dualHardware[1]);
517                //RegistraLog(msglog,false);
518                result = dbi_conn_queryf(dbi->conn,
519                                         "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
520                                         dualHardware[0]);
521                if (!result) {
522                        dbi_conn_error(dbi->conn, &msglog);
523                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
524                               __func__, __LINE__, msglog);
525                        return false;
526                }
527                if (!dbi_result_next_row(result)) { //  Tipo de Hardware NO existente
528                        dbi_result_free(result);
529                        return false;
530                } else { //  Tipo de Hardware Existe
531                        idtipohardware = dbi_result_get_uint(result, "idtipohardware");
532                        dbi_result_free(result);
533
534                        result = dbi_conn_queryf(dbi->conn,
535                                                 "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
536                                                 idtipohardware, dualHardware[1]);
537
538                        if (!result) {
539                                dbi_conn_error(dbi->conn, &msglog);
540                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
541                                       __func__, __LINE__, msglog);
542                                return false;
543                        }
544
545                        if (!dbi_result_next_row(result)) { //  Hardware NO existente
546                                dbi_result_free(result);
547                                result = dbi_conn_queryf(dbi->conn,
548                                                        "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
549                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
550                                                dualHardware[1], idc);
551                                if (!result) {
552                                        dbi_conn_error(dbi->conn, &msglog);
553                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
554                                               __func__, __LINE__, msglog);
555                                        return false;
556                                }
557
558                                // Recupera el identificador del hardware
559                                tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
560                        } else {
561                                tbidhardware[i] = dbi_result_get_uint(result, "idhardware");
562                        }
563                        dbi_result_free(result);
564                }
565        }
566        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
567
568        for (i = 0; i < lon - 1; i++) {
569                for (j = i + 1; j < lon; j++) {
570                        if (tbidhardware[i] > tbidhardware[j]) {
571                                aux = tbidhardware[i];
572                                tbidhardware[i] = tbidhardware[j];
573                                tbidhardware[j] = aux;
574                        }
575                }
576        }
577        /* Crea cadena de identificadores de componentes hardware separados por coma */
578        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
579        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
580        idhardwares = calloc(1, sizeof(aux) * lon + lon);
581        if (idhardwares == NULL) {
582                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
583                return false;
584        }
585        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
586        for (i = 1; i < lon; i++)
587                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
588
589        if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares,
590                        npc, tbidhardware, lon)) {
591                syslog(LOG_ERR, "Problem updating client hardware\n");
592                retval=false;
593        } else {
594                retval=true;
595        }
596        free(whard);
597        free(idhardwares);
598
599        return (retval);
600}
601// ________________________________________________________________________________________________________
602// Función: cuestionPerfilHardware
603//
604//              Descripción:
605//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
606//              Parámetros:
607//                      - db: Objeto base de datos (ya operativo)
608//                      - tbl: Objeto tabla
609//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
610//                      - ido: Identificador del ordenador
611//                      - tbidhardware: Identificador del tipo de hardware
612//                      - con: Número de componentes detectados para configurar un el perfil hardware
613//                      - npc: Nombre del cliente
614// ________________________________________________________________________________________________________
615bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido,
616                int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
617                int lon)
618{
619        const char *msglog;
620        dbi_result result;
621        int i;
622        int nwidperfilhard;
623
624        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
625        result = dbi_conn_queryf(dbi->conn,
626                "SELECT idperfilhard FROM"
627                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
628                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
629                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
630                " FROM  perfileshard_hardwares"
631                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
632                " WHERE idhardwares LIKE '%s'", idhardwares);
633
634        if (!result) {
635                dbi_conn_error(dbi->conn, &msglog);
636                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
637                       __func__, __LINE__, msglog);
638                return false;
639        }
640        if (!dbi_result_next_row(result)) {
641                // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
642                dbi_result_free(result);
643                result = dbi_conn_queryf(dbi->conn,
644                                "INSERT perfileshard  (descripcion,idcentro,grupoid)"
645                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
646                if (!result) {
647                        dbi_conn_error(dbi->conn, &msglog);
648                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
649                               __func__, __LINE__, msglog);
650                        return false;
651                }
652                dbi_result_free(result);
653
654                // Recupera el identificador del nuevo perfil hardware
655                nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL);
656
657                // Crea la relación entre perfiles y componenetes hardware
658                for (i = 0; i < lon; i++) {
659                        result = dbi_conn_queryf(dbi->conn,
660                                        "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
661                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
662                        if (!result) {
663                                dbi_conn_error(dbi->conn, &msglog);
664                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
665                                       __func__, __LINE__, msglog);
666                                return false;
667                        }
668                        dbi_result_free(result);
669                }
670        } else { // Existe un perfil con todos esos componentes
671                nwidperfilhard = dbi_result_get_uint(result, "idperfilhard");
672                dbi_result_free(result);
673        }
674        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
675                // Actualiza el identificador del perfil hardware del ordenador
676                result = dbi_conn_queryf(dbi->conn,
677                        "UPDATE ordenadores SET idperfilhard=%d"
678                        " WHERE idordenador=%s", nwidperfilhard, ido);
679                if (!result) {
680                        dbi_conn_error(dbi->conn, &msglog);
681                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
682                               __func__, __LINE__, msglog);
683                        return false;
684                }
685                dbi_result_free(result);
686        }
687        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
688        result = dbi_conn_queryf(dbi->conn,
689                "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
690                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
691                " (SELECT DISTINCT idperfilhard from ordenadores))");
692        if (!result) {
693                dbi_conn_error(dbi->conn, &msglog);
694                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
695                       __func__, __LINE__, msglog);
696                return false;
697        }
698        dbi_result_free(result);
699
700        /* Eliminar Perfiles hardware que quedan húerfanos */
701        result = dbi_conn_queryf(dbi->conn,
702                        "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
703                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
704        if (!result) {
705                dbi_conn_error(dbi->conn, &msglog);
706                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
707                       __func__, __LINE__, msglog);
708                return false;
709        }
710        dbi_result_free(result);
711
712        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
713        result = dbi_conn_queryf(dbi->conn,
714                        "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
715                        " (SELECT idperfilhard FROM perfileshard)");
716        if (!result) {
717                dbi_conn_error(dbi->conn, &msglog);
718                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
719                       __func__, __LINE__, msglog);
720                return false;
721        }
722        dbi_result_free(result);
723
724        return true;
725}
726// ________________________________________________________________________________________________________
727// Función: actualizaSoftware
728//
729//      Descripción:
730//              Actualiza la base de datos con la configuración software del cliente
731//      Parámetros:
732//              - db: Objeto base de datos (ya operativo)
733//              - tbl: Objeto tabla
734//              - sft: cadena con el inventario software
735//              - par: Número de la partición
736//              - ido: Identificador del ordenador del cliente en la tabla
737//              - npc: Nombre del ordenador
738//              - idc: Identificador del centro o Unidad organizativa
739//      Devuelve:
740//              true: Si el proceso es correcto
741//              false: En caso de ocurrir algún error
742//
743//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
744// ________________________________________________________________________________________________________
745bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido,
746                       char *npc, char *idc)
747{
748        int i, j, lon, aux, idperfilsoft, idnombreso;
749        bool retval;
750        char *wsft;
751        int tbidsoftware[MAXSOFTWARE];
752        char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares;
753        const char *msglog;
754        dbi_result result;
755
756        /* Toma Centro (Unidad Organizativa) y perfil software */
757        result = dbi_conn_queryf(dbi->conn,
758                "SELECT idperfilsoft,numpar"
759                " FROM ordenadores_particiones"
760                " WHERE idordenador=%s", ido);
761        if (!result) {
762                dbi_conn_error(dbi->conn, &msglog);
763                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
764                       __func__, __LINE__, msglog);
765                return false;
766        }
767        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
768        while (dbi_result_next_row(result)) {
769                aux = dbi_result_get_uint(result, "numpar");
770                if (aux == atoi(par)) { // Se encuentra la partición
771                        idperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
772                        break;
773                }
774        }
775        dbi_result_free(result);
776        wsft=escaparCadena(sft); // Codificar comillas simples
777        if(!wsft)
778                return false;
779
780        /* Recorre componentes software*/
781        lon = splitCadena(tbSoftware, wsft, '\n');
782
783        if (lon == 0)
784                return true; // No hay lineas que procesar
785        if (lon > MAXSOFTWARE)
786                lon = MAXSOFTWARE; // Limita el número de componentes software
787
788        idnombreso = 0;
789        for (i = 0; i < lon; i++) {
790                // Primera línea es el sistema operativo: se obtiene identificador
791                if (i == 0) {
792                        idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
793                        continue;
794                }
795
796                result = dbi_conn_queryf(dbi->conn,
797                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
798                                rTrim(tbSoftware[i]));
799                if (!result) {
800                        dbi_conn_error(dbi->conn, &msglog);
801                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
802                               __func__, __LINE__, msglog);
803                        return false;
804                }
805
806                if (!dbi_result_next_row(result)) {
807                        dbi_result_free(result);
808                        result = dbi_conn_queryf(dbi->conn,
809                                                "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
810                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
811                        if (!result) { // Error al insertar
812                                dbi_conn_error(dbi->conn, &msglog);
813                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
814                                       __func__, __LINE__, msglog);
815                                return false;
816                        }
817
818                        // Recupera el identificador del software
819                        tbidsoftware[i - 1] = dbi_conn_sequence_last(dbi->conn, NULL);
820                } else {
821                        tbidsoftware[i - 1] = dbi_result_get_uint(result, "idsoftware");
822                }
823                dbi_result_free(result);
824        }
825        lon--;
826
827        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
828
829        for (i = 0; i < lon - 1; i++) {
830                for (j = i + 1; j < lon; j++) {
831                        if (tbidsoftware[i] > tbidsoftware[j]) {
832                                aux = tbidsoftware[i];
833                                tbidsoftware[i] = tbidsoftware[j];
834                                tbidsoftware[j] = aux;
835                        }
836                }
837        }
838        /* Crea cadena de identificadores de componentes software separados por coma */
839        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
840        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
841        idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon);
842        if (idsoftwares == NULL) {
843                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
844                return false;
845        }
846        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
847        for (i = 1; i < lon; i++)
848                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
849
850        // Comprueba existencia de perfil software y actualización de éste para el ordenador
851        if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares,
852                        npc, par, tbidsoftware, lon)) {
853                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
854                       __func__, __LINE__, msglog);
855                retval=false;
856        } else {
857                retval=true;
858        }
859        free(wsft);
860        free(idsoftwares);
861
862        return retval;
863}
864// ________________________________________________________________________________________________________
865// Función: CuestionPerfilSoftware
866//
867//      Parámetros:
868//              - db: Objeto base de datos (ya operativo)
869//              - tbl: Objeto tabla
870//              - idcentro: Identificador del centro en la tabla
871//              - ido: Identificador del ordenador del cliente en la tabla
872//              - idnombreso: Identificador del sistema operativo
873//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
874//              - npc: Nombre del ordenador del cliente
875//              - particion: Número de la partición
876//              - tbidsoftware: Array con los identificadores de componentes software
877//              - lon: Número de componentes
878//      Devuelve:
879//              true: Si el proceso es correcto
880//              false: En caso de ocurrir algún error
881//
882//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
883//_________________________________________________________________________________________________________
884bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
885                            int idperfilsoftware, int idnombreso,
886                            char *idsoftwares, char *npc, char *par,
887                            int *tbidsoftware, int lon)
888{
889        int i, nwidperfilsoft;
890        const char *msglog;
891        dbi_result result;
892
893        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
894        result = dbi_conn_queryf(dbi->conn,
895                "SELECT idperfilsoft FROM"
896                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
897                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
898                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
899                " FROM  perfilessoft_softwares"
900                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
901                " WHERE idsoftwares LIKE '%s'", idsoftwares);
902
903        if (!result) {
904                dbi_conn_error(dbi->conn, &msglog);
905                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
906                       __func__, __LINE__, msglog);
907                return false;
908        }
909        if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea
910                dbi_result_free(result);
911                result = dbi_conn_queryf(dbi->conn,
912                                "INSERT perfilessoft  (descripcion, idcentro, grupoid, idnombreso)"
913                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
914                if (!result) {
915                        dbi_conn_error(dbi->conn, &msglog);
916                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
917                               __func__, __LINE__, msglog);
918                        return false;
919                }
920
921                dbi_result_free(result);
922                // Recupera el identificador del nuevo perfil software
923                nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL);
924
925                // Crea la relación entre perfiles y componenetes software
926                for (i = 0; i < lon; i++) {
927                        result = dbi_conn_queryf(dbi->conn,
928                                                "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
929                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
930                        if (!result) {
931                                dbi_conn_error(dbi->conn, &msglog);
932                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
933                                       __func__, __LINE__, msglog);
934                                return false;
935                        }
936                        dbi_result_free(result);
937                }
938        } else { // Existe un perfil con todos esos componentes
939                nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
940                dbi_result_free(result);
941        }
942
943        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
944                // Actualiza el identificador del perfil software del ordenador
945                result = dbi_conn_queryf(dbi->conn,
946                                "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
947                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
948                if (!result) { // Error al insertar
949                        dbi_conn_error(dbi->conn, &msglog);
950                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
951                               __func__, __LINE__, msglog);
952                        return false;
953                }
954                dbi_result_free(result);
955        }
956
957        /* DEPURACIÓN DE PERFILES SOFTWARE */
958
959        /* Eliminar Perfiles software que quedan húerfanos */
960        result = dbi_conn_queryf(dbi->conn,
961                "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
962                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
963                " AND  idperfilsoft NOT IN"\
964                " (SELECT DISTINCT idperfilsoft from imagenes)");
965        if (!result) {
966                dbi_conn_error(dbi->conn, &msglog);
967                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
968                       __func__, __LINE__, msglog);
969                return false;
970        }
971        dbi_result_free(result),
972
973        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
974        result = dbi_conn_queryf(dbi->conn,
975                        "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
976                        " (SELECT idperfilsoft from perfilessoft)");
977        if (!result) {
978                dbi_conn_error(dbi->conn, &msglog);
979                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
980                       __func__, __LINE__, msglog);
981                return false;
982        }
983        dbi_result_free(result);
984
985        return true;
986}
Note: See TracBrowser for help on using the repository browser.