summaryrefslogtreecommitdiffstats
path: root/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c302
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) {