From 5d97a721d0d475ea86e9d503a2e413e22f53492b Mon Sep 17 00:00:00 2001 From: OpenGnSys Support Team Date: Thu, 19 Sep 2024 10:30:46 +0200 Subject: ogAdmServer: replace old actualizaConfiguracion Reimplement the legacy funcion actualizaConfiguracion with og_update_client_config in src/client.c if disk does not exist, add it, otherwise update disk contents. if partition size, code, filesystem or os is different, reset image id, otherwise update partition usage only. delete partitions that are gone at the end. --- src/client.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 285 insertions(+), 17 deletions(-) (limited to 'src/client.c') 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) { -- cgit v1.2.3-18-g5258