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

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

#1042 incorrect initialization of software profiles array

The position 0 of the software profiles array is not initialized,
this triggers a bug randomly on image creation if the position 0
comes zero. Adjust the loop to initialize position 0 accordingly.

  • Property mode set to 100644
File size: 35.8 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
274// ________________________________________________________________________________________________________
275// Función: Levanta
276//
277//      Descripción:
278//              Enciende ordenadores a través de la red cuyas macs se pasan como parámetro
279//      Parámetros:
280//              - iph: Cadena de direcciones ip separadas por ";"
281//              - mac: Cadena de direcciones mac separadas por ";"
282//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
283//      Devuelve:
284//              true: Si el proceso es correcto
285//              false: En caso de ocurrir algún error
286// ________________________________________________________________________________________________________
287
288bool Levanta(char *ptrIP[], char *ptrMacs[], char *ptrNetmasks[], int lon,
289             char *mar)
290{
291        int i, s;
292
293        s = wol_socket_open();
294        if (s < 0)
295                return false;
296
297        for (i = 0; i < lon; i++) {
298                if (!WakeUp(s, ptrIP[i], ptrMacs[i], ptrNetmasks[i], mar)) {
299                        syslog(LOG_ERR, "problem sending magic packet\n");
300                        close(s);
301                        return false;
302                }
303        }
304        close(s);
305        return true;
306}
307
308enum wol_delivery_type {
309        OG_WOL_BROADCAST = 1,
310        OG_WOL_UNICAST = 2
311};
312
313//_____________________________________________________________________________________________________________
314// Función: WakeUp
315//
316//       Descripción:
317//              Enciende el ordenador cuya MAC se pasa como parámetro
318//      Parámetros:
319//              - s : Socket para enviar trama magic packet
320//              - iph : Cadena con la dirección ip
321//              - mac : Cadena con la dirección mac en formato XXXXXXXXXXXX
322//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
323//      Devuelve:
324//              true: Si el proceso es correcto
325//              false: En caso de ocurrir algún error
326//_____________________________________________________________________________________________________________
327//
328bool WakeUp(int s, char* iph, char *mac, char *netmask, char *mar)
329{
330        struct in_addr addr, netmask_addr, broadcast_addr ={};
331        unsigned int macaddr[OG_WOL_MACADDR_LEN];
332        char HDaddress_bin[OG_WOL_MACADDR_LEN];
333        struct sockaddr_in WakeUpCliente;
334        struct wol_msg Trama_WakeUp;
335        bool ret;
336        int i;
337
338        if (!inet_aton(iph, &addr)) {
339                syslog(LOG_ERR, "bad IP address\n");
340                return false;
341        }
342
343        if (!inet_aton(netmask, &netmask_addr)) {
344                syslog(LOG_ERR, "bad netmask address: %s\n", netmask);
345                return false;
346        }
347
348        broadcast_addr.s_addr = addr.s_addr | ~netmask_addr.s_addr;
349
350        for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF)
351                Trama_WakeUp.secuencia_FF[i] = 0xFF;
352
353        sscanf(mac, "%02x%02x%02x%02x%02x%02x",
354               &macaddr[0], &macaddr[1], &macaddr[2],
355               &macaddr[3], &macaddr[4], &macaddr[5]);
356
357        for (i = 0; i < 6; i++)
358                HDaddress_bin[i] = (uint8_t)macaddr[i];
359
360        for (i = 0; i < 16; i++) // Segunda secuencia de la trama Wake Up , repetir 16 veces su la MAC
361                memcpy(&Trama_WakeUp.macbin[i][0], &HDaddress_bin, 6);
362
363        /* Creación de socket del cliente que recibe la trama magic packet */
364        WakeUpCliente.sin_family = AF_INET;
365        WakeUpCliente.sin_port = htons((short) PUERTO_WAKEUP);
366
367        switch (atoi(mar)) {
368        case OG_WOL_BROADCAST:
369                ret = wake_up_broadcast(s, &WakeUpCliente, &Trama_WakeUp);
370                ret &= wake_up_send(s, &WakeUpCliente, &Trama_WakeUp,
371                                    &broadcast_addr);
372                break;
373        case OG_WOL_UNICAST:
374                ret = wake_up_send(s, &WakeUpCliente, &Trama_WakeUp, &addr);
375                break;
376        default:
377                syslog(LOG_ERR, "unknown wol type\n");
378                ret = false;
379                break;
380        }
381        return ret;
382}
383
384// ________________________________________________________________________________________________________
385// Función: actualizaCreacionImagen
386//
387//      Descripción:
388//              Esta función actualiza la base de datos con el resultado de la creación de una imagen
389//      Parámetros:
390//              - db: Objeto base de datos (ya operativo)
391//              - tbl: Objeto tabla
392//              - idi: Identificador de la imagen
393//              - dsk: Disco de donde se creó
394//              - par: Partición de donde se creó
395//              - cpt: Código de partición
396//              - ipr: Ip del repositorio
397//              - ido: Identificador del ordenador modelo
398//      Devuelve:
399//              true: Si el proceso es correcto
400//              false: En caso de ocurrir algún error
401// ________________________________________________________________________________________________________
402bool actualizaCreacionImagen(struct og_dbi *dbi, char *idi, char *dsk,
403                             char *par, char *cpt, char *ipr, char *ido)
404{
405        const char *msglog;
406        dbi_result result;
407        int idr,ifs;
408
409        /* Toma identificador del repositorio correspondiente al ordenador modelo */
410        result = dbi_conn_queryf(dbi->conn,
411                        "SELECT repositorios.idrepositorio"
412                        "  FROM repositorios"
413                        "  LEFT JOIN ordenadores USING (idrepositorio)"
414                        " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
415
416        if (!result) {
417                dbi_conn_error(dbi->conn, &msglog);
418                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
419                       __func__, __LINE__, msglog);
420                return false;
421        }
422        if (!dbi_result_next_row(result)) {
423                syslog(LOG_ERR,
424                       "repository does not exist in database (%s:%d)\n",
425                       __func__, __LINE__);
426                dbi_result_free(result);
427                return false;
428        }
429        idr = dbi_result_get_uint(result, "idrepositorio");
430        dbi_result_free(result);
431
432        /* Toma identificador del perfilsoftware */
433        result = dbi_conn_queryf(dbi->conn,
434                        "SELECT idperfilsoft"
435                        "  FROM ordenadores_particiones"
436                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
437
438        if (!result) {
439                dbi_conn_error(dbi->conn, &msglog);
440                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
441                       __func__, __LINE__, msglog);
442                return false;
443        }
444        if (!dbi_result_next_row(result)) {
445                syslog(LOG_ERR,
446                       "software profile does not exist in database (%s:%d)\n",
447                       __func__, __LINE__);
448                dbi_result_free(result);
449                return false;
450        }
451        ifs = dbi_result_get_uint(result, "idperfilsoft");
452        dbi_result_free(result);
453
454        /* Actualizar los datos de la imagen */
455        result = dbi_conn_queryf(dbi->conn,
456                "UPDATE imagenes"
457                "   SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
458                "       idperfilsoft=%d, idrepositorio=%d,"
459                "       fechacreacion=NOW(), revision=revision+1"
460                " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
461
462        if (!result) {
463                dbi_conn_error(dbi->conn, &msglog);
464                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
465                       __func__, __LINE__, msglog);
466                return false;
467        }
468        dbi_result_free(result);
469
470        /* Actualizar los datos en el cliente */
471        result = dbi_conn_queryf(dbi->conn,
472                "UPDATE ordenadores_particiones"
473                "   SET idimagen=%s, revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
474                "       fechadespliegue=NOW()"
475                " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
476                idi, idi, ido, dsk, par);
477        if (!result) {
478                dbi_conn_error(dbi->conn, &msglog);
479                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
480                       __func__, __LINE__, msglog);
481                return false;
482        }
483        dbi_result_free(result);
484
485        return true;
486}
487
488// ________________________________________________________________________________________________________
489// Función: actualizaRestauracionImagen
490//
491//      Descripción:
492//              Esta función actualiza la base de datos con el resultado de la restauración de una imagen
493//      Parámetros:
494//              - db: Objeto base de datos (ya operativo)
495//              - tbl: Objeto tabla
496//              - idi: Identificador de la imagen
497//              - dsk: Disco de donde se restauró
498//              - par: Partición de donde se restauró
499//              - ido: Identificador del cliente donde se restauró
500//              - ifs: Identificador del perfil software contenido      en la imagen
501//      Devuelve:
502//              true: Si el proceso es correcto
503//              false: En caso de ocurrir algún error
504// ________________________________________________________________________________________________________
505bool actualizaRestauracionImagen(struct og_dbi *dbi, char *idi,
506                                 char *dsk, char *par, char *ido, char *ifs)
507{
508        const char *msglog;
509        dbi_result result;
510
511        /* Actualizar los datos de la imagen */
512        result = dbi_conn_queryf(dbi->conn,
513                        "UPDATE ordenadores_particiones"
514                        "   SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
515                        "       revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
516                        "       idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
517                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", idi, ifs, idi, ifs, ido, dsk, par);
518
519        if (!result) {
520                dbi_conn_error(dbi->conn, &msglog);
521                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
522                       __func__, __LINE__, msglog);
523                return false;
524        }
525        dbi_result_free(result);
526
527        return true;
528}
529// ________________________________________________________________________________________________________
530// Función: actualizaHardware
531//
532//              Descripción:
533//                      Actualiza la base de datos con la configuracion hardware del cliente
534//              Parámetros:
535//                      - db: Objeto base de datos (ya operativo)
536//                      - tbl: Objeto tabla
537//                      - hrd: cadena con el inventario hardware
538//                      - ido: Identificador del ordenador
539//                      - npc: Nombre del ordenador
540//                      - idc: Identificador del centro o Unidad organizativa
541// ________________________________________________________________________________________________________
542//
543bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc,
544                       char *idc)
545{
546        const char *msglog;
547        int idtipohardware, idperfilhard;
548        int lon, i, j, aux;
549        bool retval;
550        char *whard;
551        int tbidhardware[MAXHARDWARE];
552        char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares;
553        dbi_result result;
554
555        /* Toma Centro (Unidad Organizativa) */
556        result = dbi_conn_queryf(dbi->conn,
557                                 "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s",
558                                 ido);
559        if (!result) {
560                dbi_conn_error(dbi->conn, &msglog);
561                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
562                       __func__, __LINE__, msglog);
563                return false;
564        }
565        if (!dbi_result_next_row(result)) {
566                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
567                       __func__, __LINE__);
568                dbi_result_free(result);
569                return false;
570        }
571        idperfilhard = dbi_result_get_uint(result, "idperfilhard");
572        dbi_result_free(result);
573
574        whard=escaparCadena(hrd); // Codificar comillas simples
575        if(!whard)
576                return false;
577        /* Recorre componentes hardware*/
578        lon = splitCadena(tbHardware, whard, '\n');
579        if (lon > MAXHARDWARE)
580                lon = MAXHARDWARE; // Limita el número de componentes hardware
581        /*
582         for (i=0;i<lon;i++){
583         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
584         RegistraLog(msglog,false);
585         }
586         */
587        for (i = 0; i < lon; i++) {
588                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
589                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
590                //RegistraLog(msglog,false);
591                //sprintf(msglog,"valor: %s",dualHardware[1]);
592                //RegistraLog(msglog,false);
593                result = dbi_conn_queryf(dbi->conn,
594                                         "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
595                                         dualHardware[0]);
596                if (!result) {
597                        dbi_conn_error(dbi->conn, &msglog);
598                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
599                               __func__, __LINE__, msglog);
600                        return false;
601                }
602                if (!dbi_result_next_row(result)) { //  Tipo de Hardware NO existente
603                        dbi_result_free(result);
604                        return false;
605                } else { //  Tipo de Hardware Existe
606                        idtipohardware = dbi_result_get_uint(result, "idtipohardware");
607                        dbi_result_free(result);
608
609                        result = dbi_conn_queryf(dbi->conn,
610                                                 "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
611                                                 idtipohardware, dualHardware[1]);
612
613                        if (!result) {
614                                dbi_conn_error(dbi->conn, &msglog);
615                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
616                                       __func__, __LINE__, msglog);
617                                return false;
618                        }
619
620                        if (!dbi_result_next_row(result)) { //  Hardware NO existente
621                                dbi_result_free(result);
622                                result = dbi_conn_queryf(dbi->conn,
623                                                        "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
624                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
625                                                dualHardware[1], idc);
626                                if (!result) {
627                                        dbi_conn_error(dbi->conn, &msglog);
628                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
629                                               __func__, __LINE__, msglog);
630                                        return false;
631                                }
632
633                                // Recupera el identificador del hardware
634                                tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
635                        } else {
636                                tbidhardware[i] = dbi_result_get_uint(result, "idhardware");
637                        }
638                        dbi_result_free(result);
639                }
640        }
641        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
642
643        for (i = 0; i < lon - 1; i++) {
644                for (j = i + 1; j < lon; j++) {
645                        if (tbidhardware[i] > tbidhardware[j]) {
646                                aux = tbidhardware[i];
647                                tbidhardware[i] = tbidhardware[j];
648                                tbidhardware[j] = aux;
649                        }
650                }
651        }
652        /* Crea cadena de identificadores de componentes hardware separados por coma */
653        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
654        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
655        idhardwares = calloc(1, sizeof(aux) * lon + lon);
656        if (idhardwares == NULL) {
657                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
658                return false;
659        }
660        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
661        for (i = 1; i < lon; i++)
662                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
663
664        if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares,
665                        npc, tbidhardware, lon)) {
666                syslog(LOG_ERR, "Problem updating client hardware\n");
667                retval=false;
668        } else {
669                retval=true;
670        }
671        free(whard);
672        free(idhardwares);
673
674        return (retval);
675}
676// ________________________________________________________________________________________________________
677// Función: cuestionPerfilHardware
678//
679//              Descripción:
680//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
681//              Parámetros:
682//                      - db: Objeto base de datos (ya operativo)
683//                      - tbl: Objeto tabla
684//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
685//                      - ido: Identificador del ordenador
686//                      - tbidhardware: Identificador del tipo de hardware
687//                      - con: Número de componentes detectados para configurar un el perfil hardware
688//                      - npc: Nombre del cliente
689// ________________________________________________________________________________________________________
690bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido,
691                int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
692                int lon)
693{
694        const char *msglog;
695        dbi_result result;
696        int i;
697        int nwidperfilhard;
698
699        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
700        result = dbi_conn_queryf(dbi->conn,
701                "SELECT idperfilhard FROM"
702                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
703                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
704                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
705                " FROM  perfileshard_hardwares"
706                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
707                " WHERE idhardwares LIKE '%s'", idhardwares);
708
709        if (!result) {
710                dbi_conn_error(dbi->conn, &msglog);
711                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
712                       __func__, __LINE__, msglog);
713                return false;
714        }
715        if (!dbi_result_next_row(result)) {
716                // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
717                dbi_result_free(result);
718                result = dbi_conn_queryf(dbi->conn,
719                                "INSERT perfileshard  (descripcion,idcentro,grupoid)"
720                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
721                if (!result) {
722                        dbi_conn_error(dbi->conn, &msglog);
723                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
724                               __func__, __LINE__, msglog);
725                        return false;
726                }
727                dbi_result_free(result);
728
729                // Recupera el identificador del nuevo perfil hardware
730                nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL);
731
732                // Crea la relación entre perfiles y componenetes hardware
733                for (i = 0; i < lon; i++) {
734                        result = dbi_conn_queryf(dbi->conn,
735                                        "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
736                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
737                        if (!result) {
738                                dbi_conn_error(dbi->conn, &msglog);
739                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
740                                       __func__, __LINE__, msglog);
741                                return false;
742                        }
743                        dbi_result_free(result);
744                }
745        } else { // Existe un perfil con todos esos componentes
746                nwidperfilhard = dbi_result_get_uint(result, "idperfilhard");
747                dbi_result_free(result);
748        }
749        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
750                // Actualiza el identificador del perfil hardware del ordenador
751                result = dbi_conn_queryf(dbi->conn,
752                        "UPDATE ordenadores SET idperfilhard=%d"
753                        " WHERE idordenador=%s", nwidperfilhard, ido);
754                if (!result) {
755                        dbi_conn_error(dbi->conn, &msglog);
756                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
757                               __func__, __LINE__, msglog);
758                        return false;
759                }
760                dbi_result_free(result);
761        }
762        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
763        result = dbi_conn_queryf(dbi->conn,
764                "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
765                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
766                " (SELECT DISTINCT idperfilhard from ordenadores))");
767        if (!result) {
768                dbi_conn_error(dbi->conn, &msglog);
769                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
770                       __func__, __LINE__, msglog);
771                return false;
772        }
773        dbi_result_free(result);
774
775        /* Eliminar Perfiles hardware que quedan húerfanos */
776        result = dbi_conn_queryf(dbi->conn,
777                        "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
778                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
779        if (!result) {
780                dbi_conn_error(dbi->conn, &msglog);
781                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
782                       __func__, __LINE__, msglog);
783                return false;
784        }
785        dbi_result_free(result);
786
787        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
788        result = dbi_conn_queryf(dbi->conn,
789                        "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
790                        " (SELECT idperfilhard FROM perfileshard)");
791        if (!result) {
792                dbi_conn_error(dbi->conn, &msglog);
793                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
794                       __func__, __LINE__, msglog);
795                return false;
796        }
797        dbi_result_free(result);
798
799        return true;
800}
801// ________________________________________________________________________________________________________
802// Función: actualizaSoftware
803//
804//      Descripción:
805//              Actualiza la base de datos con la configuración software del cliente
806//      Parámetros:
807//              - db: Objeto base de datos (ya operativo)
808//              - tbl: Objeto tabla
809//              - sft: cadena con el inventario software
810//              - par: Número de la partición
811//              - ido: Identificador del ordenador del cliente en la tabla
812//              - npc: Nombre del ordenador
813//              - idc: Identificador del centro o Unidad organizativa
814//      Devuelve:
815//              true: Si el proceso es correcto
816//              false: En caso de ocurrir algún error
817//
818//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
819// ________________________________________________________________________________________________________
820bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido,
821                       char *npc, char *idc)
822{
823        int i, j, lon, aux, idperfilsoft, idnombreso;
824        bool retval;
825        char *wsft;
826        int tbidsoftware[MAXSOFTWARE];
827        char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares;
828        const char *msglog;
829        dbi_result result;
830
831        /* Toma Centro (Unidad Organizativa) y perfil software */
832        result = dbi_conn_queryf(dbi->conn,
833                "SELECT idperfilsoft,numpar"
834                " FROM ordenadores_particiones"
835                " WHERE idordenador=%s", ido);
836        if (!result) {
837                dbi_conn_error(dbi->conn, &msglog);
838                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
839                       __func__, __LINE__, msglog);
840                return false;
841        }
842        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
843        while (dbi_result_next_row(result)) {
844                aux = dbi_result_get_uint(result, "numpar");
845                if (aux == atoi(par)) { // Se encuentra la partición
846                        idperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
847                        break;
848                }
849        }
850        dbi_result_free(result);
851        wsft=escaparCadena(sft); // Codificar comillas simples
852        if(!wsft)
853                return false;
854
855        /* Recorre componentes software*/
856        lon = splitCadena(tbSoftware, wsft, '\n');
857
858        if (lon == 0)
859                return true; // No hay lineas que procesar
860        if (lon > MAXSOFTWARE)
861                lon = MAXSOFTWARE; // Limita el número de componentes software
862
863        idnombreso = 0;
864        for (i = 0; i < lon; i++) {
865                // Primera línea es el sistema operativo: se obtiene identificador
866                if (i == 0) {
867                        idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
868                        continue;
869                }
870
871                result = dbi_conn_queryf(dbi->conn,
872                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
873                                rTrim(tbSoftware[i]));
874                if (!result) {
875                        dbi_conn_error(dbi->conn, &msglog);
876                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
877                               __func__, __LINE__, msglog);
878                        return false;
879                }
880
881                if (!dbi_result_next_row(result)) {
882                        dbi_result_free(result);
883                        result = dbi_conn_queryf(dbi->conn,
884                                                "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
885                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
886                        if (!result) { // Error al insertar
887                                dbi_conn_error(dbi->conn, &msglog);
888                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
889                                       __func__, __LINE__, msglog);
890                                return false;
891                        }
892
893                        // Recupera el identificador del software
894                        tbidsoftware[i - 1] = dbi_conn_sequence_last(dbi->conn, NULL);
895                } else {
896                        tbidsoftware[i - 1] = dbi_result_get_uint(result, "idsoftware");
897                }
898                dbi_result_free(result);
899        }
900        lon--;
901
902        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
903
904        for (i = 0; i < lon - 1; i++) {
905                for (j = i + 1; j < lon; j++) {
906                        if (tbidsoftware[i] > tbidsoftware[j]) {
907                                aux = tbidsoftware[i];
908                                tbidsoftware[i] = tbidsoftware[j];
909                                tbidsoftware[j] = aux;
910                        }
911                }
912        }
913        /* Crea cadena de identificadores de componentes software separados por coma */
914        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
915        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
916        idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon);
917        if (idsoftwares == NULL) {
918                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
919                return false;
920        }
921        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
922        for (i = 1; i < lon; i++)
923                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
924
925        // Comprueba existencia de perfil software y actualización de éste para el ordenador
926        if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares,
927                        npc, par, tbidsoftware, lon)) {
928                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
929                       __func__, __LINE__, msglog);
930                retval=false;
931        } else {
932                retval=true;
933        }
934        free(wsft);
935        free(idsoftwares);
936
937        return retval;
938}
939// ________________________________________________________________________________________________________
940// Función: CuestionPerfilSoftware
941//
942//      Parámetros:
943//              - db: Objeto base de datos (ya operativo)
944//              - tbl: Objeto tabla
945//              - idcentro: Identificador del centro en la tabla
946//              - ido: Identificador del ordenador del cliente en la tabla
947//              - idnombreso: Identificador del sistema operativo
948//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
949//              - npc: Nombre del ordenador del cliente
950//              - particion: Número de la partición
951//              - tbidsoftware: Array con los identificadores de componentes software
952//              - lon: Número de componentes
953//      Devuelve:
954//              true: Si el proceso es correcto
955//              false: En caso de ocurrir algún error
956//
957//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
958//_________________________________________________________________________________________________________
959bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
960                            int idperfilsoftware, int idnombreso,
961                            char *idsoftwares, char *npc, char *par,
962                            int *tbidsoftware, int lon)
963{
964        int i, nwidperfilsoft;
965        const char *msglog;
966        dbi_result result;
967
968        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
969        result = dbi_conn_queryf(dbi->conn,
970                "SELECT idperfilsoft FROM"
971                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
972                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
973                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
974                " FROM  perfilessoft_softwares"
975                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
976                " WHERE idsoftwares LIKE '%s'", idsoftwares);
977
978        if (!result) {
979                dbi_conn_error(dbi->conn, &msglog);
980                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
981                       __func__, __LINE__, msglog);
982                return false;
983        }
984        if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea
985                dbi_result_free(result);
986                result = dbi_conn_queryf(dbi->conn,
987                                "INSERT perfilessoft  (descripcion, idcentro, grupoid, idnombreso)"
988                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
989                if (!result) {
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
996                dbi_result_free(result);
997                // Recupera el identificador del nuevo perfil software
998                nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL);
999
1000                // Crea la relación entre perfiles y componenetes software
1001                for (i = 0; i < lon; i++) {
1002                        result = dbi_conn_queryf(dbi->conn,
1003                                                "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
1004                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
1005                        if (!result) {
1006                                dbi_conn_error(dbi->conn, &msglog);
1007                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1008                                       __func__, __LINE__, msglog);
1009                                return false;
1010                        }
1011                        dbi_result_free(result);
1012                }
1013        } else { // Existe un perfil con todos esos componentes
1014                nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
1015                dbi_result_free(result);
1016        }
1017
1018        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
1019                // Actualiza el identificador del perfil software del ordenador
1020                result = dbi_conn_queryf(dbi->conn,
1021                                "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
1022                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
1023                if (!result) { // Error al insertar
1024                        dbi_conn_error(dbi->conn, &msglog);
1025                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1026                               __func__, __LINE__, msglog);
1027                        return false;
1028                }
1029                dbi_result_free(result);
1030        }
1031
1032        /* DEPURACIÓN DE PERFILES SOFTWARE */
1033
1034        /* Eliminar Perfiles software que quedan húerfanos */
1035        result = dbi_conn_queryf(dbi->conn,
1036                "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
1037                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
1038                " AND  idperfilsoft NOT IN"\
1039                " (SELECT DISTINCT idperfilsoft from imagenes)");
1040        if (!result) {
1041                dbi_conn_error(dbi->conn, &msglog);
1042                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1043                       __func__, __LINE__, msglog);
1044                return false;
1045        }
1046        dbi_result_free(result),
1047
1048        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
1049        result = dbi_conn_queryf(dbi->conn,
1050                        "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
1051                        " (SELECT idperfilsoft from perfilessoft)");
1052        if (!result) {
1053                dbi_conn_error(dbi->conn, &msglog);
1054                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1055                       __func__, __LINE__, msglog);
1056                return false;
1057        }
1058        dbi_result_free(result);
1059
1060        return true;
1061}
Note: See TracBrowser for help on using the repository browser.