diff options
Diffstat (limited to 'src/client.c')
-rw-r--r-- | src/client.c | 302 |
1 files changed, 285 insertions, 17 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) { |