summaryrefslogtreecommitdiffstats
path: root/src/ogAdmServer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ogAdmServer.c')
-rw-r--r--src/ogAdmServer.c1301
1 files changed, 1301 insertions, 0 deletions
diff --git a/src/ogAdmServer.c b/src/ogAdmServer.c
new file mode 100644
index 0000000..436c3b1
--- /dev/null
+++ b/src/ogAdmServer.c
@@ -0,0 +1,1301 @@
+// *******************************************************************************************************
+// Servicio: ogAdmServer
+// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
+// Fecha Creación: Marzo-2010
+// Fecha Última modificación: Marzo-2010
+// Nombre del fichero: ogAdmServer.cpp
+// Descripción :Este fichero implementa el servicio de administración general del sistema
+// *******************************************************************************************************
+#include "ogAdmServer.h"
+#include "dbi.h"
+#include "utils.h"
+#include "list.h"
+#include "rest.h"
+#include "client.h"
+#include "json.h"
+#include "schedule.h"
+#include <syslog.h>
+#include <sys/ioctl.h>
+#include <ifaddrs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <jansson.h>
+#include <time.h>
+
+char usuario[LONPRM]; // Usuario de acceso a la base de datos
+char pasguor[LONPRM]; // Password del usuario
+char datasource[LONPRM]; // Dirección IP del gestor de base de datos
+char catalog[LONPRM]; // Nombre de la base de datos
+char interface[LONPRM]; // Interface name
+char auth_token[LONPRM]; // API token
+
+struct og_dbi_config dbi_config = {
+ .user = usuario,
+ .passwd = pasguor,
+ .host = datasource,
+ .database = catalog,
+};
+
+//________________________________________________________________________________________________________
+// Función: tomaConfiguracion
+//
+// Descripción:
+// Lee el fichero de configuración del servicio
+// Parámetros:
+// filecfg : Ruta completa al fichero de configuración
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+//________________________________________________________________________________________________________
+bool tomaConfiguracion(const char *filecfg)
+{
+ char buf[1024], *line;
+ char *key, *value;
+ FILE *fcfg;
+
+ if (filecfg == NULL || strlen(filecfg) == 0) {
+ syslog(LOG_ERR, "No configuration file has been specified\n");
+ return false;
+ }
+
+ fcfg = fopen(filecfg, "rt");
+ if (fcfg == NULL) {
+ syslog(LOG_ERR, "Cannot open configuration file `%s'\n",
+ filecfg);
+ return false;
+ }
+
+ servidoradm[0] = '\0'; //inicializar variables globales
+
+ line = fgets(buf, sizeof(buf), fcfg);
+ while (line != NULL) {
+ const char *delim = "=";
+
+ line[strlen(line) - 1] = '\0';
+
+ key = strtok(line, delim);
+ value = strtok(NULL, delim);
+
+ if (!strcmp(str_toupper(key), "SERVIDORADM"))
+ snprintf(servidoradm, sizeof(servidoradm), "%s", value);
+ else if (!strcmp(str_toupper(key), "PUERTO"))
+ snprintf(puerto, sizeof(puerto), "%s", value);
+ else if (!strcmp(str_toupper(key), "USUARIO"))
+ snprintf(usuario, sizeof(usuario), "%s", value);
+ else if (!strcmp(str_toupper(key), "PASSWORD"))
+ snprintf(pasguor, sizeof(pasguor), "%s", value);
+ else if (!strcmp(str_toupper(key), "DATASOURCE"))
+ snprintf(datasource, sizeof(datasource), "%s", value);
+ else if (!strcmp(str_toupper(key), "CATALOG"))
+ snprintf(catalog, sizeof(catalog), "%s", value);
+ else if (!strcmp(str_toupper(key), "INTERFACE"))
+ snprintf(interface, sizeof(interface), "%s", value);
+ else if (!strcmp(str_toupper(key), "APITOKEN"))
+ snprintf(auth_token, sizeof(auth_token), "%s", value);
+
+ line = fgets(buf, sizeof(buf), fcfg);
+ }
+
+ fclose(fcfg);
+
+ if (!servidoradm[0]) {
+ syslog(LOG_ERR, "Missing SERVIDORADM in configuration file\n");
+ return false;
+ }
+ if (!puerto[0]) {
+ syslog(LOG_ERR, "Missing PUERTO in configuration file\n");
+ return false;
+ }
+ if (!usuario[0]) {
+ syslog(LOG_ERR, "Missing USUARIO in configuration file\n");
+ return false;
+ }
+ if (!pasguor[0]) {
+ syslog(LOG_ERR, "Missing PASSWORD in configuration file\n");
+ return false;
+ }
+ if (!datasource[0]) {
+ syslog(LOG_ERR, "Missing DATASOURCE in configuration file\n");
+ return false;
+ }
+ if (!catalog[0]) {
+ syslog(LOG_ERR, "Missing CATALOG in configuration file\n");
+ return false;
+ }
+ if (!interface[0])
+ syslog(LOG_ERR, "Missing INTERFACE in configuration file\n");
+
+ return true;
+}
+
+#define OG_CMD_MAXLEN 64
+
+// ________________________________________________________________________________________________________
+// Función: clienteDisponible
+//
+// Descripción:
+// Comprueba la disponibilidad del cliente para recibir comandos interactivos
+// Parametros:
+// - ip : La ip del cliente a buscar
+// - idx: (Salida) Indice que ocupa el cliente, de estar ya registrado
+// Devuelve:
+// true: Si el cliente está disponible
+// false: En caso contrario
+// ________________________________________________________________________________________________________
+bool clienteDisponible(char *ip, int* idx)
+{
+ int estado;
+
+ if (clienteExistente(ip, idx)) {
+ estado = strcmp(tbsockets[*idx].estado, CLIENTE_OCUPADO); // Cliente ocupado
+ if (estado == 0)
+ return false;
+
+ estado = strcmp(tbsockets[*idx].estado, CLIENTE_APAGADO); // Cliente apagado
+ if (estado == 0)
+ return false;
+
+ estado = strcmp(tbsockets[*idx].estado, CLIENTE_INICIANDO); // Cliente en proceso de inclusión
+ if (estado == 0)
+ return false;
+
+ return true; // En caso contrario el cliente está disponible
+ }
+ return false; // Cliente no está registrado en el sistema
+}
+// ________________________________________________________________________________________________________
+// Función: clienteExistente
+//
+// Descripción:
+// Comprueba si el cliente está registrado en la tabla de socket del sistema
+// Parametros:
+// - ip : La ip del cliente a buscar
+// - idx:(Salida) Indice que ocupa el cliente, de estar ya registrado
+// Devuelve:
+// true: Si el cliente está registrado
+// false: En caso contrario
+// ________________________________________________________________________________________________________
+bool clienteExistente(char *ip, int* idx)
+{
+ int i;
+ for (i = 0; i < MAXIMOS_CLIENTES; i++) {
+ if (contieneIP(ip, tbsockets[i].ip)) { // Si existe la IP en la cadena
+ *idx = i;
+ return true;
+ }
+ }
+ return false;
+}
+// ________________________________________________________________________________________________________
+// Función: actualizaConfiguracion
+//
+// Descripción:
+// Esta función actualiza la base de datos con la configuracion de particiones de un cliente
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - cfg: cadena con una Configuración
+// - ido: Identificador del ordenador cliente
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+// Especificaciones:
+// Los parametros de la configuración son:
+// par= Número de partición
+// cpt= Codigo o tipo de partición
+// sfi= Sistema de ficheros que está implementado en la partición
+// soi= Nombre del sistema de ficheros instalado en la partición
+// tam= Tamaño de la partición
+// ________________________________________________________________________________________________________
+bool actualizaConfiguracion(struct og_dbi *dbi, char *cfg, int ido)
+{
+ int lon, p, c,i, dato, swu, idsoi, idsfi,k;
+ char *ptrPar[MAXPAR], *ptrCfg[7], *ptrDual[2], tbPar[LONSTD];
+ char *ser, *disk, *par, *cpt, *sfi, *soi, *tam, *uso; // Parametros de configuración.
+ dbi_result result, result_update;
+ const char *msglog;
+
+ lon = 0;
+ p = splitCadena(ptrPar, cfg, '\n');
+ for (i = 0; i < p; i++) {
+ c = splitCadena(ptrCfg, ptrPar[i], '\t');
+
+ // Si la 1ª línea solo incluye el número de serie del equipo; actualizar BD.
+ if (i == 0 && c == 1) {
+ splitCadena(ptrDual, ptrCfg[0], '=');
+ ser = ptrDual[1];
+ if (strlen(ser) > 0) {
+ // Solo actualizar si número de serie no existía.
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores SET numserie='%s'"
+ " WHERE idordenador=%d AND numserie IS NULL",
+ ser, ido);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+ }
+ continue;
+ }
+
+ // Distribución de particionado.
+ disk = par = cpt = sfi = soi = tam = uso = NULL;
+
+ splitCadena(ptrDual, ptrCfg[0], '=');
+ disk = ptrDual[1]; // Número de disco
+
+ splitCadena(ptrDual, ptrCfg[1], '=');
+ par = ptrDual[1]; // Número de partición
+
+ k=splitCadena(ptrDual, ptrCfg[2], '=');
+ if(k==2){
+ cpt = ptrDual[1]; // Código de partición
+ }else{
+ cpt = (char*)"0";
+ }
+
+ k=splitCadena(ptrDual, ptrCfg[3], '=');
+ if(k==2){
+ sfi = ptrDual[1]; // Sistema de ficheros
+ /* Comprueba existencia del s0xistema de ficheros instalado */
+ idsfi = checkDato(dbi, sfi, "sistemasficheros", "descripcion","idsistemafichero");
+ }
+ else
+ idsfi=0;
+
+ k=splitCadena(ptrDual, ptrCfg[4], '=');
+ if(k==2){ // Sistema operativo detecdtado
+ soi = ptrDual[1]; // Nombre del S.O. instalado
+ /* Comprueba existencia del sistema operativo instalado */
+ idsoi = checkDato(dbi, soi, "nombresos", "nombreso", "idnombreso");
+ }
+ else
+ idsoi=0;
+
+ splitCadena(ptrDual, ptrCfg[5], '=');
+ tam = ptrDual[1]; // Tamaño de la partición
+
+ splitCadena(ptrDual, ptrCfg[6], '=');
+ uso = ptrDual[1]; // Porcentaje de uso del S.F.
+
+ lon += sprintf(tbPar + lon, "(%s, %s),", disk, par);
+
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT numdisk, numpar, tamano, uso, idsistemafichero, idnombreso"
+ " FROM ordenadores_particiones"
+ " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
+ ido, disk, par);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) {
+ result_update = dbi_conn_queryf(dbi->conn,
+ "INSERT INTO ordenadores_particiones(idordenador,numdisk,numpar,codpar,tamano,uso,idsistemafichero,idnombreso,idimagen)"
+ " VALUES(%d,%s,%s,0x%s,%s,%s,%d,%d,0)",
+ ido, disk, par, cpt, tam, uso, idsfi, idsoi);
+ if (!result_update) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result_update);
+
+ } else { // Existe el registro
+ swu = true; // Se supone que algún dato ha cambiado
+
+ dato = dbi_result_get_uint(result, "tamano");
+ if (atoi(tam) == dato) {// Parámetro tamaño igual al almacenado
+ dato = dbi_result_get_uint(result, "idsistemafichero");
+ if (idsfi == dato) {// Parámetro sistema de fichero igual al almacenado
+ dato = dbi_result_get_uint(result, "idnombreso");
+ if (idsoi == dato) {// Parámetro sistema de fichero distinto al almacenado
+ swu = false; // Todos los parámetros de la partición son iguales, no se actualiza
+ }
+ }
+ }
+ if (swu) { // Hay que actualizar los parámetros de la partición
+ result_update = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores_particiones SET "
+ " codpar=0x%s,"
+ " tamano=%s,"
+ " uso=%s,"
+ " idsistemafichero=%d,"
+ " idnombreso=%d,"
+ " idimagen=0,"
+ " idperfilsoft=0,"
+ " fechadespliegue=NULL"
+ " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
+ cpt, tam, uso, idsfi, idsoi, ido, disk, par);
+ } else { // Actualizar porcentaje de uso.
+ result_update = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores_particiones SET "
+ " codpar=0x%s,"
+ " uso=%s"
+ " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
+ cpt, uso, ido, disk, par);
+ }
+ if (!result_update) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ dbi_result_free(result_update);
+ }
+ dbi_result_free(result);
+ }
+ lon += sprintf(tbPar + lon, "(0,0)");
+ // Eliminar particiones almacenadas que ya no existen
+ result_update = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)",
+ ido, tbPar);
+ if (!result_update) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result_update);
+
+ return true;
+}
+// ________________________________________________________________________________________________________
+// Función: checkDato
+//
+// Descripción:
+// Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en
+// cualquier caso el identificador del registro existenet o del insertado
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - dato: Dato
+// - tabla: Nombre de la tabla
+// - nomdato: Nombre del dato en la tabla
+// - nomidentificador: Nombre del identificador en la tabla
+// Devuelve:
+// El identificador del registro existente o el del insertado
+//
+// Especificaciones:
+// En caso de producirse algún error se devuelve el valor 0
+// ________________________________________________________________________________________________________
+
+int checkDato(struct og_dbi *dbi, char *dato, const char *tabla,
+ const char *nomdato, const char *nomidentificador)
+{
+ const char *msglog;
+ int identificador;
+ dbi_result result;
+
+ if (strlen(dato) == 0)
+ return (0); // EL dato no tiene valor
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador,
+ tabla, nomdato, dato);
+
+ // Ejecuta consulta
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return (0);
+ }
+ if (!dbi_result_next_row(result)) { // Software NO existente
+ dbi_result_free(result);
+
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return (0);
+ }
+ // Recupera el identificador del software
+ identificador = dbi_conn_sequence_last(dbi->conn, NULL);
+ } else {
+ identificador = dbi_result_get_uint(result, nomidentificador);
+ }
+ dbi_result_free(result);
+
+ return (identificador);
+}
+
+// ________________________________________________________________________________________________________
+// Función: Levanta
+//
+// Descripción:
+// Enciende ordenadores a través de la red cuyas macs se pasan como parámetro
+// Parámetros:
+// - iph: Cadena de direcciones ip separadas por ";"
+// - mac: Cadena de direcciones mac separadas por ";"
+// - mar: Método de arranque (1=Broadcast, 2=Unicast)
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+// ________________________________________________________________________________________________________
+
+bool Levanta(char *ptrIP[], char *ptrMacs[], int lon, char *mar)
+{
+ unsigned int on = 1;
+ struct sockaddr_in local;
+ int i, res;
+ int s;
+
+ /* Creación de socket para envío de magig packet */
+ s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0) {
+ syslog(LOG_ERR, "cannot create socket for magic packet\n");
+ return false;
+ }
+ res = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (unsigned int *) &on,
+ sizeof(on));
+ if (res < 0) {
+ syslog(LOG_ERR, "cannot set broadcast socket\n");
+ return false;
+ }
+ memset(&local, 0, sizeof(local));
+ local.sin_family = AF_INET;
+ local.sin_port = htons(PUERTO_WAKEUP);
+ local.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ for (i = 0; i < lon; i++) {
+ if (!WakeUp(s, ptrIP[i], ptrMacs[i], mar)) {
+ syslog(LOG_ERR, "problem sending magic packet\n");
+ close(s);
+ return false;
+ }
+ }
+ close(s);
+ return true;
+}
+
+#define OG_WOL_SEQUENCE 6
+#define OG_WOL_MACADDR_LEN 6
+#define OG_WOL_REPEAT 16
+
+struct wol_msg {
+ char secuencia_FF[OG_WOL_SEQUENCE];
+ char macbin[OG_WOL_REPEAT][OG_WOL_MACADDR_LEN];
+};
+
+static bool wake_up_broadcast(int sd, struct sockaddr_in *client,
+ const struct wol_msg *msg)
+{
+ struct sockaddr_in *broadcast_addr;
+ struct ifaddrs *ifaddr, *ifa;
+ int ret;
+
+ if (getifaddrs(&ifaddr) < 0) {
+ syslog(LOG_ERR, "cannot get list of addresses\n");
+ return false;
+ }
+
+ client->sin_addr.s_addr = htonl(INADDR_BROADCAST);
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL ||
+ ifa->ifa_addr->sa_family != AF_INET ||
+ strcmp(ifa->ifa_name, interface) != 0)
+ continue;
+
+ broadcast_addr =
+ (struct sockaddr_in *)ifa->ifa_ifu.ifu_broadaddr;
+ client->sin_addr.s_addr = broadcast_addr->sin_addr.s_addr;
+ break;
+ }
+ freeifaddrs(ifaddr);
+
+ ret = sendto(sd, msg, sizeof(*msg), 0,
+ (struct sockaddr *)client, sizeof(*client));
+ if (ret < 0) {
+ syslog(LOG_ERR, "failed to send broadcast wol\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool wake_up_unicast(int sd, struct sockaddr_in *client,
+ const struct wol_msg *msg,
+ const struct in_addr *addr)
+{
+ int ret;
+
+ client->sin_addr.s_addr = addr->s_addr;
+
+ ret = sendto(sd, msg, sizeof(*msg), 0,
+ (struct sockaddr *)client, sizeof(*client));
+ if (ret < 0) {
+ syslog(LOG_ERR, "failed to send unicast wol\n");
+ return false;
+ }
+
+ return true;
+}
+
+enum wol_delivery_type {
+ OG_WOL_BROADCAST = 1,
+ OG_WOL_UNICAST = 2
+};
+
+//_____________________________________________________________________________________________________________
+// Función: WakeUp
+//
+// Descripción:
+// Enciende el ordenador cuya MAC se pasa como parámetro
+// Parámetros:
+// - s : Socket para enviar trama magic packet
+// - iph : Cadena con la dirección ip
+// - mac : Cadena con la dirección mac en formato XXXXXXXXXXXX
+// - mar: Método de arranque (1=Broadcast, 2=Unicast)
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+//_____________________________________________________________________________________________________________
+//
+bool WakeUp(int s, char* iph, char *mac, char *mar)
+{
+ unsigned int macaddr[OG_WOL_MACADDR_LEN];
+ char HDaddress_bin[OG_WOL_MACADDR_LEN];
+ struct sockaddr_in WakeUpCliente;
+ struct wol_msg Trama_WakeUp;
+ struct in_addr addr;
+ bool ret;
+ int i;
+
+ for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF)
+ Trama_WakeUp.secuencia_FF[i] = 0xFF;
+
+ sscanf(mac, "%02x%02x%02x%02x%02x%02x",
+ &macaddr[0], &macaddr[1], &macaddr[2],
+ &macaddr[3], &macaddr[4], &macaddr[5]);
+
+ for (i = 0; i < 6; i++)
+ HDaddress_bin[i] = (uint8_t)macaddr[i];
+
+ for (i = 0; i < 16; i++) // Segunda secuencia de la trama Wake Up , repetir 16 veces su la MAC
+ memcpy(&Trama_WakeUp.macbin[i][0], &HDaddress_bin, 6);
+
+ /* Creación de socket del cliente que recibe la trama magic packet */
+ WakeUpCliente.sin_family = AF_INET;
+ WakeUpCliente.sin_port = htons((short) PUERTO_WAKEUP);
+
+ switch (atoi(mar)) {
+ case OG_WOL_BROADCAST:
+ ret = wake_up_broadcast(s, &WakeUpCliente, &Trama_WakeUp);
+ break;
+ case OG_WOL_UNICAST:
+ if (inet_aton(iph, &addr) < 0) {
+ syslog(LOG_ERR, "bad IP address for unicast wol\n");
+ ret = false;
+ break;
+ }
+ ret = wake_up_unicast(s, &WakeUpCliente, &Trama_WakeUp, &addr);
+ break;
+ default:
+ syslog(LOG_ERR, "unknown wol type\n");
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+// ________________________________________________________________________________________________________
+// Función: actualizaCreacionImagen
+//
+// Descripción:
+// Esta función actualiza la base de datos con el resultado de la creación de una imagen
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - idi: Identificador de la imagen
+// - dsk: Disco de donde se creó
+// - par: Partición de donde se creó
+// - cpt: Código de partición
+// - ipr: Ip del repositorio
+// - ido: Identificador del ordenador modelo
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+// ________________________________________________________________________________________________________
+bool actualizaCreacionImagen(struct og_dbi *dbi, char *idi, char *dsk,
+ char *par, char *cpt, char *ipr, char *ido)
+{
+ const char *msglog;
+ dbi_result result;
+ int idr,ifs;
+
+ /* Toma identificador del repositorio correspondiente al ordenador modelo */
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT repositorios.idrepositorio"
+ " FROM repositorios"
+ " LEFT JOIN ordenadores USING (idrepositorio)"
+ " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) {
+ syslog(LOG_ERR,
+ "repository does not exist in database (%s:%d)\n",
+ __func__, __LINE__);
+ dbi_result_free(result);
+ return false;
+ }
+ idr = dbi_result_get_uint(result, "idrepositorio");
+ dbi_result_free(result);
+
+ /* Toma identificador del perfilsoftware */
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idperfilsoft"
+ " FROM ordenadores_particiones"
+ " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) {
+ syslog(LOG_ERR,
+ "software profile does not exist in database (%s:%d)\n",
+ __func__, __LINE__);
+ dbi_result_free(result);
+ return false;
+ }
+ ifs = dbi_result_get_uint(result, "idperfilsoft");
+ dbi_result_free(result);
+
+ /* Actualizar los datos de la imagen */
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE imagenes"
+ " SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
+ " idperfilsoft=%d, idrepositorio=%d,"
+ " fechacreacion=NOW(), revision=revision+1"
+ " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ /* Actualizar los datos en el cliente */
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores_particiones"
+ " SET idimagen=%s, revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
+ " fechadespliegue=NOW()"
+ " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
+ idi, idi, ido, dsk, par);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ return true;
+}
+
+// ________________________________________________________________________________________________________
+// Función: actualizaRestauracionImagen
+//
+// Descripción:
+// Esta función actualiza la base de datos con el resultado de la restauración de una imagen
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - idi: Identificador de la imagen
+// - dsk: Disco de donde se restauró
+// - par: Partición de donde se restauró
+// - ido: Identificador del cliente donde se restauró
+// - ifs: Identificador del perfil software contenido en la imagen
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+// ________________________________________________________________________________________________________
+bool actualizaRestauracionImagen(struct og_dbi *dbi, char *idi,
+ char *dsk, char *par, char *ido, char *ifs)
+{
+ const char *msglog;
+ dbi_result result;
+
+ /* Actualizar los datos de la imagen */
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores_particiones"
+ " SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
+ " revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
+ " idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
+ " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", idi, ifs, idi, ifs, ido, dsk, par);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ return true;
+}
+// ________________________________________________________________________________________________________
+// Función: actualizaHardware
+//
+// Descripción:
+// Actualiza la base de datos con la configuracion hardware del cliente
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - hrd: cadena con el inventario hardware
+// - ido: Identificador del ordenador
+// - npc: Nombre del ordenador
+// - idc: Identificador del centro o Unidad organizativa
+// ________________________________________________________________________________________________________
+//
+bool actualizaHardware(struct og_dbi *dbi, char *hrd, char *ido, char *npc,
+ char *idc)
+{
+ const char *msglog;
+ int idtipohardware, idperfilhard;
+ int lon, i, j, aux;
+ bool retval;
+ char *whard;
+ int tbidhardware[MAXHARDWARE];
+ char *tbHardware[MAXHARDWARE],*dualHardware[2], strInt[LONINT], *idhardwares;
+ dbi_result result;
+
+ /* Toma Centro (Unidad Organizativa) */
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idperfilhard FROM ordenadores WHERE idordenador=%s",
+ ido);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) {
+ syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
+ __func__, __LINE__);
+ dbi_result_free(result);
+ return false;
+ }
+ idperfilhard = dbi_result_get_uint(result, "idperfilhard");
+ dbi_result_free(result);
+
+ whard=escaparCadena(hrd); // Codificar comillas simples
+ if(!whard)
+ return false;
+ /* Recorre componentes hardware*/
+ lon = splitCadena(tbHardware, whard, '\n');
+ if (lon > MAXHARDWARE)
+ lon = MAXHARDWARE; // Limita el número de componentes hardware
+ /*
+ for (i=0;i<lon;i++){
+ sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
+ RegistraLog(msglog,false);
+ }
+ */
+ for (i = 0; i < lon; i++) {
+ splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
+ //sprintf(msglog,"nemonico: %s",dualHardware[0]);
+ //RegistraLog(msglog,false);
+ //sprintf(msglog,"valor: %s",dualHardware[1]);
+ //RegistraLog(msglog,false);
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
+ dualHardware[0]);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) { // Tipo de Hardware NO existente
+ dbi_result_free(result);
+ return false;
+ } else { // Tipo de Hardware Existe
+ idtipohardware = dbi_result_get_uint(result, "idtipohardware");
+ dbi_result_free(result);
+
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
+ idtipohardware, dualHardware[1]);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ if (!dbi_result_next_row(result)) { // Hardware NO existente
+ dbi_result_free(result);
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
+ " VALUES(%d,'%s',%s,0)", idtipohardware,
+ dualHardware[1], idc);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ // Recupera el identificador del hardware
+ tbidhardware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
+ } else {
+ tbidhardware[i] = dbi_result_get_uint(result, "idhardware");
+ }
+ dbi_result_free(result);
+ }
+ }
+ // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
+
+ for (i = 0; i < lon - 1; i++) {
+ for (j = i + 1; j < lon; j++) {
+ if (tbidhardware[i] > tbidhardware[j]) {
+ aux = tbidhardware[i];
+ tbidhardware[i] = tbidhardware[j];
+ tbidhardware[j] = aux;
+ }
+ }
+ }
+ /* Crea cadena de identificadores de componentes hardware separados por coma */
+ sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
+ aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
+ idhardwares = calloc(1, sizeof(aux) * lon + lon);
+ if (idhardwares == NULL) {
+ syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
+ return false;
+ }
+ aux = sprintf(idhardwares, "%d", tbidhardware[0]);
+ for (i = 1; i < lon; i++)
+ aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
+
+ if (!cuestionPerfilHardware(dbi, idc, ido, idperfilhard, idhardwares,
+ npc, tbidhardware, lon)) {
+ syslog(LOG_ERR, "Problem updating client hardware\n");
+ retval=false;
+ } else {
+ retval=true;
+ }
+ free(whard);
+ free(idhardwares);
+
+ return (retval);
+}
+// ________________________________________________________________________________________________________
+// Función: cuestionPerfilHardware
+//
+// Descripción:
+// Comprueba existencia de perfil hardware y actualización de éste para el ordenador
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
+// - ido: Identificador del ordenador
+// - tbidhardware: Identificador del tipo de hardware
+// - con: Número de componentes detectados para configurar un el perfil hardware
+// - npc: Nombre del cliente
+// ________________________________________________________________________________________________________
+bool cuestionPerfilHardware(struct og_dbi *dbi, char *idc, char *ido,
+ int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
+ int lon)
+{
+ const char *msglog;
+ dbi_result result;
+ int i;
+ int nwidperfilhard;
+
+ // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idperfilhard FROM"
+ " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
+ " group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
+ " ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
+ " FROM perfileshard_hardwares"
+ " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
+ " WHERE idhardwares LIKE '%s'", idhardwares);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) {
+ // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
+ dbi_result_free(result);
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT perfileshard (descripcion,idcentro,grupoid)"
+ " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ // Recupera el identificador del nuevo perfil hardware
+ nwidperfilhard = dbi_conn_sequence_last(dbi->conn, NULL);
+
+ // Crea la relación entre perfiles y componenetes hardware
+ for (i = 0; i < lon; i++) {
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT perfileshard_hardwares (idperfilhard,idhardware)"
+ " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+ }
+ } else { // Existe un perfil con todos esos componentes
+ nwidperfilhard = dbi_result_get_uint(result, "idperfilhard");
+ dbi_result_free(result);
+ }
+ if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
+ // Actualiza el identificador del perfil hardware del ordenador
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores SET idperfilhard=%d"
+ " WHERE idordenador=%s", nwidperfilhard, ido);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+ }
+ /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
+ " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
+ " (SELECT DISTINCT idperfilhard from ordenadores))");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ /* Eliminar Perfiles hardware que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
+ " (SELECT DISTINCT idperfilhard FROM ordenadores)");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
+ " (SELECT idperfilhard FROM perfileshard)");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ return true;
+}
+// ________________________________________________________________________________________________________
+// Función: actualizaSoftware
+//
+// Descripción:
+// Actualiza la base de datos con la configuración software del cliente
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - sft: cadena con el inventario software
+// - par: Número de la partición
+// - ido: Identificador del ordenador del cliente en la tabla
+// - npc: Nombre del ordenador
+// - idc: Identificador del centro o Unidad organizativa
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+//
+// Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
+// ________________________________________________________________________________________________________
+bool actualizaSoftware(struct og_dbi *dbi, char *sft, char *par,char *ido,
+ char *npc, char *idc)
+{
+ int i, j, lon, aux, idperfilsoft, idnombreso;
+ bool retval;
+ char *wsft;
+ int tbidsoftware[MAXSOFTWARE];
+ char *tbSoftware[MAXSOFTWARE], strInt[LONINT], *idsoftwares;
+ const char *msglog;
+ dbi_result result;
+
+ /* Toma Centro (Unidad Organizativa) y perfil software */
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idperfilsoft,numpar"
+ " FROM ordenadores_particiones"
+ " WHERE idordenador=%s", ido);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
+ while (dbi_result_next_row(result)) {
+ aux = dbi_result_get_uint(result, "numpar");
+ if (aux == atoi(par)) { // Se encuentra la partición
+ idperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
+ break;
+ }
+ }
+ dbi_result_free(result);
+ wsft=escaparCadena(sft); // Codificar comillas simples
+ if(!wsft)
+ return false;
+
+ /* Recorre componentes software*/
+ lon = splitCadena(tbSoftware, wsft, '\n');
+
+ if (lon == 0)
+ return true; // No hay lineas que procesar
+ if (lon > MAXSOFTWARE)
+ lon = MAXSOFTWARE; // Limita el número de componentes software
+
+ idnombreso = 0;
+ for (i = 0; i < lon; i++) {
+ // Primera línea es el sistema operativo: se obtiene identificador
+ if (i == 0) {
+ idnombreso = checkDato(dbi, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
+ continue;
+ }
+
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
+ rTrim(tbSoftware[i]));
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ if (!dbi_result_next_row(result)) {
+ dbi_result_free(result);
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
+ " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
+ if (!result) { // Error al insertar
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ // Recupera el identificador del software
+ tbidsoftware[i] = dbi_conn_sequence_last(dbi->conn, NULL);
+ } else {
+ tbidsoftware[i] = dbi_result_get_uint(result, "idsoftware");
+ }
+ dbi_result_free(result);
+ }
+
+ // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
+
+ for (i = 0; i < lon - 1; i++) {
+ for (j = i + 1; j < lon; j++) {
+ if (tbidsoftware[i] > tbidsoftware[j]) {
+ aux = tbidsoftware[i];
+ tbidsoftware[i] = tbidsoftware[j];
+ tbidsoftware[j] = aux;
+ }
+ }
+ }
+ /* Crea cadena de identificadores de componentes software separados por coma */
+ sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
+ aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
+ idsoftwares = calloc(1, (sizeof(aux)+1) * lon + lon);
+ if (idsoftwares == NULL) {
+ syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
+ return false;
+ }
+ aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
+ for (i = 1; i < lon; i++)
+ aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
+
+ // Comprueba existencia de perfil software y actualización de éste para el ordenador
+ if (!cuestionPerfilSoftware(dbi, idc, ido, idperfilsoft, idnombreso, idsoftwares,
+ npc, par, tbidsoftware, lon)) {
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ retval=false;
+ } else {
+ retval=true;
+ }
+ free(wsft);
+ free(idsoftwares);
+
+ return retval;
+}
+// ________________________________________________________________________________________________________
+// Función: CuestionPerfilSoftware
+//
+// Parámetros:
+// - db: Objeto base de datos (ya operativo)
+// - tbl: Objeto tabla
+// - idcentro: Identificador del centro en la tabla
+// - ido: Identificador del ordenador del cliente en la tabla
+// - idnombreso: Identificador del sistema operativo
+// - idsoftwares: Cadena con los identificadores de componentes software separados por comas
+// - npc: Nombre del ordenador del cliente
+// - particion: Número de la partición
+// - tbidsoftware: Array con los identificadores de componentes software
+// - lon: Número de componentes
+// Devuelve:
+// true: Si el proceso es correcto
+// false: En caso de ocurrir algún error
+//
+// Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
+//_________________________________________________________________________________________________________
+bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
+ int idperfilsoftware, int idnombreso,
+ char *idsoftwares, char *npc, char *par,
+ int *tbidsoftware, int lon)
+{
+ int i, nwidperfilsoft;
+ const char *msglog;
+ dbi_result result;
+
+ // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT idperfilsoft FROM"
+ " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
+ " group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
+ " ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
+ " FROM perfilessoft_softwares"
+ " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
+ " WHERE idsoftwares LIKE '%s'", idsoftwares);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ if (!dbi_result_next_row(result)) { // No existe un perfil software con esos componentes de componentes software, lo crea
+ dbi_result_free(result);
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT perfilessoft (descripcion, idcentro, grupoid, idnombreso)"
+ " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+
+ dbi_result_free(result);
+ // Recupera el identificador del nuevo perfil software
+ nwidperfilsoft = dbi_conn_sequence_last(dbi->conn, NULL);
+
+ // Crea la relación entre perfiles y componenetes software
+ for (i = 0; i < lon; i++) {
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
+ " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+ }
+ } else { // Existe un perfil con todos esos componentes
+ nwidperfilsoft = dbi_result_get_uint(result, "idperfilsoft");
+ dbi_result_free(result);
+ }
+
+ if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
+ // Actualiza el identificador del perfil software del ordenador
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
+ " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
+ if (!result) { // Error al insertar
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+ }
+
+ /* DEPURACIÓN DE PERFILES SOFTWARE */
+
+ /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfilessoft_softwares WHERE idperfilsoft IN "\
+ " (SELECT idperfilsoft FROM perfilessoft WHERE idperfilsoft NOT IN"\
+ " (SELECT DISTINCT idperfilsoft from ordenadores_particiones) AND idperfilsoft NOT IN"\
+ " (SELECT DISTINCT idperfilsoft from imagenes))");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result),
+ /* Eliminar Perfiles software que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
+ " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
+ " AND idperfilsoft NOT IN"\
+ " (SELECT DISTINCT idperfilsoft from imagenes)");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result),
+
+ /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
+ " (SELECT idperfilsoft from perfilessoft)");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return false;
+ }
+ dbi_result_free(result);
+
+ return true;
+}