diff options
-rw-r--r-- | src/client.c | 302 | ||||
-rw-r--r-- | src/dbi.c | 61 | ||||
-rw-r--r-- | src/dbi.h | 1 | ||||
-rw-r--r-- | src/ogAdmServer.c | 193 |
4 files changed, 347 insertions, 210 deletions
diff --git a/src/client.c b/src/client.c index 96b522f..50d3373 100644 --- a/src/client.c +++ b/src/client.c @@ -30,6 +30,40 @@ #define OG_CLIENT_SESSION_OS_WINDOWS "Windows" #define OG_CLIENT_SESSION_TIMEDATE_LEN 20 +static struct { + const char *name; + uint32_t id; +} og_fs[] = { + { "EMPTY", 1 }, + { "CACHE", 2 }, + { "BTRFS", 3 }, + { "EXT3", 5 }, + { "EXT4", 6 }, + { "FAT32", 9 }, + { "HFS", 10 }, + { "HFSPLUS", 11 }, + { "NTFS", 13 }, + { "EXFAT", 18 }, + { "LINUX-SWAP", 19 }, + { "SWAP", 22 }, + { NULL, 0 }, +}; + +static uint32_t get_filesystem_id(const char *fs_name) +{ + uint32_t i; + + if (strlen(fs_name) == 0) + return 0; + + for (i = 0; og_fs[i].name != NULL; i++) { + if (!strcmp(og_fs[i].name, fs_name)) + return og_fs[i].id; + } + + return 0; +} + static void og_status_session_log(const struct og_client *cli, const char *type, const char* user, const char *os) @@ -502,17 +536,262 @@ static int og_resp_update_cache(json_t *data, struct og_client *cli) return 0; } +struct og_disk { + uint64_t size; +}; + +struct og_part { + uint32_t filesystem; + uint32_t os; + uint32_t code; + uint64_t size; + uint64_t used_size; +}; + +static bool og_update_client_disk_info(struct og_dbi *dbi, + const struct og_client *cli, + int computer_id, + const struct og_partition *disks, + uint32_t num_disks, + const struct og_partition *partitions, + uint32_t num_partitions, + const char *serial_number) +{ + struct og_disk cur_disk = {}, reported_disk = {}; + struct og_part cur_part = {}, reported_part = {}; + dbi_result result, result_update; + int disk_part_len = 0; + char disk_part[1024]; + const char *msglog; + int i; + + if (serial_number && strlen(serial_number) > 0) { + result = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores SET numserie='%s'" + " WHERE idordenador=%d AND numserie IS NULL", + serial_number, computer_id); + 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); + } + + for (i = 0; i < num_disks; i++) { + disk_part_len += snprintf(&disk_part[disk_part_len], + sizeof(disk_part) - disk_part_len, + "(%s, 0),", disks[i].disk); + + result = dbi_conn_queryf(dbi->conn, + "SELECT tamano " + " FROM ordenadores_particiones" + " WHERE idordenador=%d AND numdisk=%s AND numpar=0", + computer_id, disks[i].disk); + 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, disk_type, idimagen)" + " VALUES(%d,%s,0,0x%s,%s,0,0,0,'%s',0)", + computer_id, + disks[i].disk, + disks[i].code, + disks[i].size, + disks[i].disk_type); + 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); + + syslog(LOG_INFO, "adding disk %u with size %s to client %s\n", + i, disks[i].size, inet_ntoa(cli->addr.sin_addr)); + + continue; + } + + reported_disk.size = strtoull(disks[i].size, NULL, 0); + cur_disk.size = dbi_result_get_longlong(result, "tamano"); + + dbi_result_free(result); + + result_update = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores_particiones SET tamano=%s," + " codpar=%s, disk_type='%s' " + " WHERE idordenador=%d AND numdisk=%s AND numpar=0", + disks[i].size, disks[i].code, disks[i].disk_type, computer_id, disks[i].disk); + 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); + + if (cur_disk.size != reported_disk.size) + syslog(LOG_INFO, "disk %s in client %s has changed size, before %lu after %lu bytes\n", + disks[i].disk, inet_ntoa(cli->addr.sin_addr), cur_disk.size, reported_disk.size); + + continue; + } + + for (i = 0; i < num_partitions; i++) { + disk_part_len += snprintf(&disk_part[disk_part_len], + sizeof(disk_part) - disk_part_len, + "(%s, %s),", + partitions[i].disk, partitions[i].number); + + result = dbi_conn_queryf(dbi->conn, + "SELECT numdisk, numpar, tamano, uso, idsistemafichero, idnombreso, codpar" + " FROM ordenadores_particiones" + " WHERE idordenador=%d AND numdisk=%s AND numpar=%s", + computer_id, partitions[i].disk, partitions[i].number); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return false; + } + + reported_part.size = strtoull(partitions[i].size, NULL, 0); + reported_part.used_size = strtoull(partitions[i].used_size, NULL, 0); + reported_part.code = strtoul(partitions[i].code, NULL, 16); + reported_part.filesystem = get_filesystem_id(partitions[i].filesystem); + + if (og_dbi_get_os_id(dbi, partitions[i].os, &reported_part.os) < 0) { + 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%d,%s,%d,%d,%d,0)", + computer_id, + partitions[i].disk, + partitions[i].number, + reported_part.code, + partitions[i].size, + reported_part.used_size, + reported_part.filesystem, + reported_part.os); + 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); + + syslog(LOG_INFO, "new partition %s in disk %s client %s\n", + partitions[i].number, partitions[i].disk, inet_ntoa(cli->addr.sin_addr)); + + continue; + } + + cur_part.size = dbi_result_get_longlong(result, "tamano"); + cur_part.used_size = dbi_result_get_longlong(result, "uso"); + cur_part.code = dbi_result_get_int(result, "codpar"); + cur_part.filesystem = dbi_result_get_uint(result, "idsistemafichero"); + cur_part.os = dbi_result_get_uint(result, "idnombreso"); + dbi_result_free(result); + + if (cur_part.size != reported_part.size || + cur_part.code != reported_part.code || + cur_part.filesystem != reported_part.filesystem || + cur_part.os != reported_part.os) { + result_update = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores_particiones SET " + " codpar=0x%s," + " tamano=%s," + " uso=%d," + " idsistemafichero=%d," + " idnombreso=%d," + " idimagen=0," + " idperfilsoft=0," + " fechadespliegue=NULL" + " WHERE idordenador=%d AND numdisk=%s AND numpar=%s", + partitions[i].code, partitions[i].size, reported_part.used_size, + reported_part.filesystem, reported_part.os, computer_id, + partitions[i].disk, partitions[i].number); + + 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); + + syslog(LOG_INFO, "Disk %s partition %s in client %s has changed\n", + partitions[i].disk, partitions[i].number, inet_ntoa(cli->addr.sin_addr)); + + continue; + } + + if (cur_part.used_size == reported_part.used_size) + continue; + + result_update = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores_particiones SET " + " uso=%d" + " WHERE idordenador=%d AND numdisk=%s AND numpar=%s", + reported_part.used_size, computer_id, + partitions[i].disk, partitions[i].number); + 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); + + syslog(LOG_INFO, "partition usage in disk %s partition %s client %s has changed\n", + partitions[i].disk, partitions[i].number, inet_ntoa(cli->addr.sin_addr)); + } + /* remove trailing comma */ + disk_part[disk_part_len - 1] = '\0'; + + result_update = dbi_conn_queryf(dbi->conn, + "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)", + computer_id, disk_part); + 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; +} + static int og_resp_refresh(json_t *data, struct og_client *cli) { struct og_partition partitions[OG_PARTITION_MAX] = {}; struct og_partition disks[OG_DISK_MAX] = {}; + uint32_t num_disks = 0, num_partitions = 0; const char *serial_number = NULL; struct og_computer computer = {}; json_t *value, *cache = NULL; const char *status = NULL; LIST_HEAD(boot_entry_list); LIST_HEAD(cache_list); - char cfg[4096] = {}; struct og_dbi *dbi; uint32_t link = 0; const char *key; @@ -561,9 +840,6 @@ static int og_resp_refresh(json_t *data, struct og_client *cli) return 0; } - if (serial_number && strlen(serial_number) > 0) - snprintf(cfg, sizeof(cfg), "ser=%s\n", serial_number); - for (i = 0; i < OG_DISK_MAX; i++) { if (!disks[i].disk || !disks[i].number || !disks[i].code || !disks[i].filesystem || @@ -571,12 +847,7 @@ static int og_resp_refresh(json_t *data, struct og_client *cli) !disks[i].used_size) continue; - snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg), - "disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\tdtype=%s\n", - disks[i].disk, disks[i].number, - disks[i].code, disks[i].filesystem, - disks[i].os, disks[i].size, - disks[i].used_size, disks[i].disk_type); + num_disks++; } for (i = 0; i < OG_PARTITION_MAX; i++) { @@ -586,12 +857,7 @@ static int og_resp_refresh(json_t *data, struct og_client *cli) !partitions[i].used_size) continue; - snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg), - "disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\n", - partitions[i].disk, partitions[i].number, - partitions[i].code, partitions[i].filesystem, - partitions[i].os, partitions[i].size, - partitions[i].used_size); + num_partitions++; } dbi = og_dbi_open(&ogconfig.db); @@ -618,7 +884,9 @@ static int og_resp_refresh(json_t *data, struct og_client *cli) goto err_out; } - res = actualizaConfiguracion(dbi, cfg, computer.id); + res = og_update_client_disk_info(dbi, cli, computer.id, disks, num_disks, + partitions, num_partitions, + serial_number); og_dbi_close(dbi); if (!res) { @@ -456,3 +456,64 @@ int og_dbi_get_repository_ip(const struct og_dbi *dbi, const uint32_t repo_id, return 0; } + +int og_dbi_get_os_id(const struct og_dbi *dbi, const char *os_name, uint32_t *os_id) +{ + const char *msglog; + dbi_result result; + + if (strlen(os_name) == 0) + return 0; + + result = dbi_conn_queryf(dbi->conn, + "SELECT idnombreso FROM nombresos " + "WHERE nombreso = '%s'", os_name); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query OS id (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + if (dbi_result_next_row(result)) { + *os_id = dbi_result_get_uint(result, "idnombreso"); + dbi_result_free(result); + return 0; + } + + dbi_result_free(result); + + result = dbi_conn_queryf(dbi->conn, + "INSERT INTO nombresos (nombreso) " + "VALUES ('%s') ", os_name); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to insert OS id (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + dbi_result_free(result); + + result = dbi_conn_queryf(dbi->conn, + "SELECT idnombreso FROM nombresos " + "WHERE nombreso = '%s'", os_name); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query OS id (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + if (!dbi_result_next_row(result)) { + dbi_result_free(result); + syslog(LOG_ERR, "failed to query OS id (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + *os_id = dbi_result_get_uint(result, "idnombreso"); + dbi_result_free(result); + + return 0; +} @@ -142,5 +142,6 @@ int og_dbi_get_repository_ip(const struct og_dbi *dbi, const uint32_t repo_id, const char *client_ip, char *repository_ip); int og_dbi_get_server_ip(const struct og_dbi *dbi, const char *client_ip, char *server_ip); +int og_dbi_get_os_id(const struct og_dbi *dbi, const char *os_name, uint32_t *os_id); #endif diff --git a/src/ogAdmServer.c b/src/ogAdmServer.c index 107342d..23f0b91 100644 --- a/src/ogAdmServer.c +++ b/src/ogAdmServer.c @@ -23,199 +23,6 @@ #include <time.h> // ________________________________________________________________________________________________________ -// 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[8], *ptrDual[2], tbPar[LONSTD]; - char *ser, *disk, *disk_type, *par, *cpt, *sfi, *soi, *tam, *uso; // Parametros de configuración. - dbi_result result, result_update; - const char *msglog; - - if (cfg && strlen(cfg) == 0) { - syslog(LOG_ERR, "Empty configuration string (%s:%d)\n", - __func__, __LINE__); - return false; - } - - 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 (ser && 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 = disk_type = 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. - - k = splitCadena(ptrDual, ptrCfg[7], '='); - if (k == 2) - disk_type = ptrDual[1]; - else - disk_type = NULL; - - 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,disk_type,numpar,codpar,tamano,uso,idsistemafichero,idnombreso,idimagen)" - " VALUES(%d,%s,'%s',%s,0x%s,%s,%s,%d,%d,0)", - ido, disk, disk_type, 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_longlong(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: |