source: ogServer-Git/src/client.c @ 216986e

Last change on this file since 216986e was 6e70916, checked in by OpenGnSys Support Team <soporte-og@…>, 3 years ago

#915 remove shim code to update database after image restore command

Make direct call to dbi API to update database instead.

  • Property mode set to 100644
File size: 20.9 KB
RevLine 
[04ca20e]1/*
[a7cce8d]2 * Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu>
[04ca20e]3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Affero General Public License as published by the
[a7cce8d]6 * Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
[04ca20e]8 */
9
10#include "ogAdmServer.h"
[fe1ce97]11#include "cfg.h"
[04ca20e]12#include "dbi.h"
13#include "utils.h"
14#include "list.h"
15#include "rest.h"
16#include "json.h"
17#include "schedule.h"
18#include <syslog.h>
19#include <sys/ioctl.h>
20#include <ifaddrs.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <jansson.h>
25#include <time.h>
26
[ff9dbd9]27static int og_status_session_start(struct og_client *cli)
[772811e]28{
29        switch (cli->status) {
30        case OG_CLIENT_STATUS_LINUX:
31                cli->status = OG_CLIENT_STATUS_LINUX_SESSION;
32                break;
33        case OG_CLIENT_STATUS_WIN:
34                cli->status = OG_CLIENT_STATUS_WIN_SESSION;
35                break;
[ff9dbd9]36        default:
37                syslog(LOG_ERR, "%s:%d: invalid session start for status %d\n",
38                       __FILE__, __LINE__, cli->status);
39                return -1;
40        }
41        return 0;
42}
43
44static int og_status_session_stop(struct og_client *cli)
45{
46        switch (cli->status) {
[772811e]47        case OG_CLIENT_STATUS_WIN_SESSION:
48                cli->status = OG_CLIENT_STATUS_WIN;
49                break;
[ff9dbd9]50        case OG_CLIENT_STATUS_LINUX_SESSION:
51                cli->status = OG_CLIENT_STATUS_LINUX;
52                break;
[772811e]53        default:
[ff9dbd9]54                syslog(LOG_ERR, "%s:%d: invalid session stop for status %d\n",
[772811e]55                       __FILE__, __LINE__, cli->status);
56                return -1;
57        }
58        return 0;
59}
60
61static int og_resp_early_hints(struct og_client *cli, json_t *data)
62{
63        const char *event, *action, *user;
64        const char *key;
65        json_t *value;
66        int err = 0;
67
68        if (json_typeof(data) != JSON_OBJECT)
69                return -1;
70
71        json_object_foreach(data, key, value) {
72                if (!strcmp(key, "event")) {
73                        err = og_json_parse_string(value, &event);
74                        if (err < 0)
75                                return err;
76                } else if (!strcmp(key, "action")) {
77                        err = og_json_parse_string(value, &action);
78                        if (err < 0)
79                                return err;
80                } else if (!strcmp(key, "user")) {
81                        err = og_json_parse_string(value, &user);
82                        if (err < 0)
83                                return err;
84                }
85        }
86
87        syslog(LOG_INFO, "Received event %s %s %s\n", event, action, user);
88
89        if (strncmp(event, "session", strlen("session")))
90                return -1;
91
[ff9dbd9]92        if (!strncmp(action, "start", strlen("start")))
93                return og_status_session_start(cli);
94        if (!strncmp(action, "stop", strlen("stop")))
95                return og_status_session_stop(cli);
[772811e]96
[ff9dbd9]97        syslog(LOG_ERR, "Invalid action for event %s %s %s\n", event, action, user);
98        return -1;
[772811e]99}
100
[04ca20e]101static int og_resp_probe(struct og_client *cli, json_t *data)
102{
103        const char *status = NULL;
104        const char *key;
[40d4279]105        uint32_t speed;
[04ca20e]106        json_t *value;
107        int err = 0;
108
109        if (json_typeof(data) != JSON_OBJECT)
110                return -1;
111
112        json_object_foreach(data, key, value) {
113                if (!strcmp(key, "status")) {
114                        err = og_json_parse_string(value, &status);
115                        if (err < 0)
116                                return err;
[40d4279]117                } else if (!strcmp(key, "speed")) {
118                        err = og_json_parse_uint(value, &speed);
119                        if (err < 0)
120                                return err;
121                        cli->speed = speed;
[04ca20e]122                }
123        }
124
125        if (!strcmp(status, "BSY"))
126                cli->status = OG_CLIENT_STATUS_BUSY;
127        else if (!strcmp(status, "OPG"))
128                cli->status = OG_CLIENT_STATUS_OGLIVE;
[c0f5d2c]129        else if (!strcmp(status, "VDI"))
130                cli->status = OG_CLIENT_STATUS_VIRTUAL;
[04ca20e]131
132        return status ? 0 : -1;
133}
134
135static int og_resp_shell_run(struct og_client *cli, json_t *data)
136{
137        const char *output = NULL;
138        char filename[4096];
139        const char *key;
140        json_t *value;
141        int err = -1;
142        FILE *file;
143
144        if (json_typeof(data) != JSON_OBJECT)
145                return -1;
146
147        json_object_foreach(data, key, value) {
148                if (!strcmp(key, "out")) {
149                        err = og_json_parse_string(value, &output);
150                        if (err < 0)
151                                return err;
152                }
153        }
154
155        if (!output) {
156                syslog(LOG_ERR, "%s:%d: malformed json response\n",
157                       __FILE__, __LINE__);
158                return -1;
159        }
160
161        sprintf(filename, "/tmp/_Seconsola_%s", inet_ntoa(cli->addr.sin_addr));
162        file = fopen(filename, "wt");
163        if (!file) {
164                syslog(LOG_ERR, "cannot open file %s: %s\n",
165                       filename, strerror(errno));
166                return -1;
167        }
168
169        fprintf(file, "%s", output);
170        fclose(file);
171
172        return 0;
173}
174
175struct og_computer_legacy  {
176        char center[OG_DB_INT_MAXLEN + 1];
177        char id[OG_DB_INT_MAXLEN + 1];
178        char hardware[8192];
179};
180
181static int og_resp_hardware(json_t *data, struct og_client *cli)
182{
183        struct og_computer_legacy legacy = {};
[cbd9421]184        struct og_computer computer = {};
[04ca20e]185        const char *hardware = NULL;
186        struct og_dbi *dbi;
187        const char *key;
188        json_t *value;
189        int err = 0;
190        bool res;
191
192        if (json_typeof(data) != JSON_OBJECT)
193                return -1;
194
195        json_object_foreach(data, key, value) {
196                if (!strcmp(key, "hardware")) {
197                        err = og_json_parse_string(value, &hardware);
198                        if (err < 0)
199                                return -1;
200                }
201        }
202
203        if (!hardware) {
204                syslog(LOG_ERR, "malformed response json\n");
205                return -1;
206        }
207
[fe1ce97]208        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]209        if (!dbi) {
210                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
211                       __func__, __LINE__);
212                return -1;
213        }
214
[d7e2022]215        err = og_dbi_get_computer_info(dbi, &computer, cli->addr.sin_addr);
216        if (err < 0) {
217                og_dbi_close(dbi);
218                return -1;
219        }
220
221        snprintf(legacy.center, sizeof(legacy.center), "%d", computer.center);
222        snprintf(legacy.id, sizeof(legacy.id), "%d", computer.id);
223        snprintf(legacy.hardware, sizeof(legacy.hardware), "%s", hardware);
224
[04ca20e]225        res = actualizaHardware(dbi, legacy.hardware, legacy.id, computer.name,
226                                legacy.center);
227        og_dbi_close(dbi);
228
229        if (!res) {
230                syslog(LOG_ERR, "Problem updating client configuration\n");
231                return -1;
232        }
233
234        return 0;
235}
236
237struct og_software_legacy {
238        char software[8192];
239        char center[OG_DB_INT_MAXLEN + 1];
240        char part[OG_DB_SMALLINT_MAXLEN + 1];
241        char id[OG_DB_INT_MAXLEN + 1];
242};
243
244static int og_resp_software(json_t *data, struct og_client *cli)
245{
246        struct og_software_legacy legacy = {};
[cbd9421]247        struct og_computer computer = {};
[04ca20e]248        const char *partition = NULL;
249        const char *software = NULL;
250        struct og_dbi *dbi;
251        const char *key;
252        json_t *value;
253        int err = 0;
254        bool res;
255
256        if (json_typeof(data) != JSON_OBJECT)
257                return -1;
258
259        json_object_foreach(data, key, value) {
260                if (!strcmp(key, "software"))
261                        err = og_json_parse_string(value, &software);
262                else if (!strcmp(key, "partition"))
263                        err = og_json_parse_string(value, &partition);
264
265                if (err < 0)
266                        return -1;
267        }
268
269        if (!software || !partition) {
270                syslog(LOG_ERR, "malformed response json\n");
271                return -1;
272        }
273
[fe1ce97]274        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]275        if (!dbi) {
276                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
277                       __func__, __LINE__);
278                return -1;
279        }
280
[d7e2022]281        err = og_dbi_get_computer_info(dbi, &computer, cli->addr.sin_addr);
282        if (err < 0) {
283                og_dbi_close(dbi);
284                return -1;
285        }
286
287        snprintf(legacy.software, sizeof(legacy.software), "%s", software);
288        snprintf(legacy.part, sizeof(legacy.part), "%s", partition);
289        snprintf(legacy.id, sizeof(legacy.id), "%d", computer.id);
290        snprintf(legacy.center, sizeof(legacy.center), "%d", computer.center);
291
[04ca20e]292        res = actualizaSoftware(dbi, legacy.software, legacy.part, legacy.id,
293                                computer.name, legacy.center);
294        og_dbi_close(dbi);
295
296        if (!res) {
297                syslog(LOG_ERR, "Problem updating client configuration\n");
298                return -1;
299        }
300
301        return 0;
302}
303
304#define OG_PARAMS_RESP_REFRESH  (OG_PARAM_PART_DISK |           \
305                                 OG_PARAM_PART_NUMBER |         \
306                                 OG_PARAM_PART_CODE |           \
307                                 OG_PARAM_PART_FILESYSTEM |     \
308                                 OG_PARAM_PART_OS |             \
309                                 OG_PARAM_PART_SIZE |           \
310                                 OG_PARAM_PART_USED_SIZE)
311
312static int og_json_parse_partition_array(json_t *value,
313                                         struct og_partition *partitions)
314{
315        json_t *element;
316        int i, err;
317
318        if (json_typeof(value) != JSON_ARRAY)
319                return -1;
320
321        for (i = 0; i < json_array_size(value) && i < OG_PARTITION_MAX; i++) {
322                element = json_array_get(value, i);
323
324                err = og_json_parse_partition(element, &partitions[i],
325                                              OG_PARAMS_RESP_REFRESH);
326                if (err < 0)
327                        return err;
328        }
329
330        return 0;
331}
332
333static int og_dbi_queue_autorun(uint32_t computer_id, uint32_t proc_id)
334{
335        struct og_task dummy_task = {
336                .scope          = computer_id,
337                .type_scope     = AMBITO_ORDENADORES,
338                .procedure_id   = proc_id,
339        };
340        struct og_dbi *dbi;
341
[fe1ce97]342        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]343        if (!dbi) {
344                syslog(LOG_ERR, "cannot open connection database "
345                                "(%s:%d)\n", __func__, __LINE__);
346                return -1;
347        }
348        if (og_dbi_queue_procedure(dbi, &dummy_task)) {
349                og_dbi_close(dbi);
350                return -1;
351        }
352        og_dbi_close(dbi);
353
354        return 0;
355}
356
357static int og_resp_refresh(json_t *data, struct og_client *cli)
358{
359        struct og_partition partitions[OG_PARTITION_MAX] = {};
[24e6fbf]360        struct og_partition disks[OG_DISK_MAX] = {};
[04ca20e]361        const char *serial_number = NULL;
362        struct og_computer computer = {};
[5a3fd51]363        const char *status = NULL;
[24e6fbf]364        char cfg[4096] = {};
[04ca20e]365        struct og_dbi *dbi;
366        const char *key;
367        unsigned int i;
368        json_t *value;
369        int err = 0;
370        bool res;
371
372        if (json_typeof(data) != JSON_OBJECT)
373                return -1;
374
375        json_object_foreach(data, key, value) {
376                if (!strcmp(key, "disk_setup")) {
[24e6fbf]377                        err = og_json_parse_partition_array(value, disks);
[04ca20e]378                } else if (!strcmp(key, "partition_setup")) {
379                        err = og_json_parse_partition_array(value, partitions);
380                } else if (!strcmp(key, "serial_number")) {
381                        err = og_json_parse_string(value, &serial_number);
[5a3fd51]382                } else if (!strcmp(key, "status")) {
383                        err = og_json_parse_string(value, &status);
[04ca20e]384                }
385
386                if (err < 0)
387                        return err;
388        }
389
[b6b1040]390        if (status) {
391                if (!strncmp(status, "LINUX", strlen("LINUX"))) {
392                        cli->status = OG_CLIENT_STATUS_LINUX;
393                } else if (!strncmp(status, "WIN", strlen("WIN"))) {
394                        cli->status = OG_CLIENT_STATUS_WIN;
395                }
[5a3fd51]396                return 0;
397        }
398
[04ca20e]399        if (strlen(serial_number) > 0)
400                snprintf(cfg, sizeof(cfg), "ser=%s\n", serial_number);
401
[24e6fbf]402        for (i = 0; i < OG_DISK_MAX; i++) {
403                if (!disks[i].disk || !disks[i].number ||
404                    !disks[i].code || !disks[i].filesystem ||
405                    !disks[i].os || !disks[i].size ||
406                    !disks[i].used_size)
407                        continue;
408
409                snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg),
[12d8fff]410                         "disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\tdtype=%s\n",
[24e6fbf]411                         disks[i].disk, disks[i].number,
412                         disks[i].code, disks[i].filesystem,
413                         disks[i].os, disks[i].size,
[12d8fff]414                         disks[i].used_size, disks[i].disk_type);
[24e6fbf]415        }
[04ca20e]416
417        for (i = 0; i < OG_PARTITION_MAX; i++) {
418                if (!partitions[i].disk || !partitions[i].number ||
419                    !partitions[i].code || !partitions[i].filesystem ||
420                    !partitions[i].os || !partitions[i].size ||
421                    !partitions[i].used_size)
422                        continue;
423
424                snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg),
425                         "disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\n",
426                         partitions[i].disk, partitions[i].number,
427                         partitions[i].code, partitions[i].filesystem,
428                         partitions[i].os, partitions[i].size,
429                         partitions[i].used_size);
430        }
431
[fe1ce97]432        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]433        if (!dbi) {
434                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
435                                  __func__, __LINE__);
436                return -1;
437        }
[d7e2022]438
439        err = og_dbi_get_computer_info(dbi, &computer, cli->addr.sin_addr);
440        if (err < 0) {
441                og_dbi_close(dbi);
442                return -1;
443        }
444
[04ca20e]445        res = actualizaConfiguracion(dbi, cfg, computer.id);
446        og_dbi_close(dbi);
447
448        if (!res) {
449                syslog(LOG_ERR, "Problem updating client configuration\n");
450                return -1;
451        }
452
453        if (!cli->autorun && computer.procedure_id) {
454                cli->autorun = true;
455
[f537daf]456                if (og_dbi_queue_autorun(computer.id, computer.procedure_id))
[04ca20e]457                        return -1;
458        }
459
460        return 0;
461}
462
[0efc182]463static int update_image_info(struct og_dbi *dbi, const char *image_id,
464                             const char *clonator, const char *compressor,
465                             const char *filesystem, const uint64_t datasize)
466{
467        const char *msglog;
468        dbi_result result;
469
470        result = dbi_conn_queryf(dbi->conn,
471                "UPDATE imagenes"
472                "   SET clonator='%s', compressor='%s',"
[a67f27a]473                "       filesystem='%s', datasize=%lld"
[0efc182]474                " WHERE idimagen=%s", clonator, compressor, filesystem,
475                datasize, image_id);
476
477        if (!result) {
478                dbi_conn_error(dbi->conn, &msglog);
479                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
480                       __func__, __LINE__, msglog);
481                return -1;
482        }
483        dbi_result_free(result);
484
485        return 0;
486}
487
[04ca20e]488static int og_resp_image_create(json_t *data, struct og_client *cli)
489{
490        struct og_software_legacy soft_legacy;
491        struct og_image_legacy img_legacy;
[cbd9421]492        struct og_computer computer = {};
[0efc182]493        const char *compressor = NULL;
494        const char *filesystem = NULL;
[04ca20e]495        const char *partition = NULL;
496        const char *software = NULL;
497        const char *image_id = NULL;
[0efc182]498        const char *clonator = NULL;
[04ca20e]499        const char *disk = NULL;
500        const char *code = NULL;
501        const char *name = NULL;
502        const char *repo = NULL;
[0efc182]503        uint64_t datasize = 0;
[04ca20e]504        struct og_dbi *dbi;
505        const char *key;
506        json_t *value;
507        int err = 0;
508        bool res;
509
510        if (json_typeof(data) != JSON_OBJECT)
511                return -1;
512
513        json_object_foreach(data, key, value) {
514                if (!strcmp(key, "software"))
515                        err = og_json_parse_string(value, &software);
516                else if (!strcmp(key, "partition"))
517                        err = og_json_parse_string(value, &partition);
518                else if (!strcmp(key, "disk"))
519                        err = og_json_parse_string(value, &disk);
520                else if (!strcmp(key, "code"))
521                        err = og_json_parse_string(value, &code);
522                else if (!strcmp(key, "id"))
523                        err = og_json_parse_string(value, &image_id);
524                else if (!strcmp(key, "name"))
525                        err = og_json_parse_string(value, &name);
526                else if (!strcmp(key, "repository"))
527                        err = og_json_parse_string(value, &repo);
[0efc182]528                else if (!strcmp(key, "clonator"))
529                        err = og_json_parse_string(value, &clonator);
530                else if (!strcmp(key, "compressor"))
531                        err = og_json_parse_string(value, &compressor);
532                else if (!strcmp(key, "filesystem"))
533                        err = og_json_parse_string(value, &filesystem);
534                else if (!strcmp(key, "datasize"))
535                        err = og_json_parse_uint64(value, &datasize);
[04ca20e]536
537                if (err < 0)
538                        return err;
539        }
540
541        if (!software || !partition || !disk || !code || !image_id || !name ||
[0efc182]542            !repo || !clonator || !compressor || !filesystem || !datasize) {
[04ca20e]543                syslog(LOG_ERR, "malformed response json\n");
544                return -1;
545        }
546
[fe1ce97]547        dbi = og_dbi_open(&ogconfig.db);
[d7e2022]548        if (!dbi) {
549                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
550                       __func__, __LINE__);
551                return -1;
552        }
553
554        err = og_dbi_get_computer_info(dbi, &computer, cli->addr.sin_addr);
555        if (err < 0) {
556                og_dbi_close(dbi);
[04ca20e]557                return -1;
[d7e2022]558        }
[04ca20e]559
560        snprintf(soft_legacy.center, sizeof(soft_legacy.center), "%d",
561                 computer.center);
562        snprintf(soft_legacy.software, sizeof(soft_legacy.software), "%s",
563                 software);
564        snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
565                 image_id);
566        snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
567        snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
568        snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
569        snprintf(img_legacy.code, sizeof(img_legacy.code), "%s", code);
570        snprintf(img_legacy.name, sizeof(img_legacy.name), "%s", name);
571        snprintf(img_legacy.repo, sizeof(img_legacy.repo), "%s", repo);
572
573        res = actualizaSoftware(dbi,
574                                soft_legacy.software,
575                                img_legacy.part,
576                                soft_legacy.id,
577                                computer.name,
578                                soft_legacy.center);
579        if (!res) {
580                og_dbi_close(dbi);
581                syslog(LOG_ERR, "Problem updating client configuration\n");
582                return -1;
583        }
584
585        res = actualizaCreacionImagen(dbi,
586                                      img_legacy.image_id,
587                                      img_legacy.disk,
588                                      img_legacy.part,
589                                      img_legacy.code,
590                                      img_legacy.repo,
591                                      soft_legacy.id);
592        if (!res) {
[0efc182]593                og_dbi_close(dbi);
[04ca20e]594                syslog(LOG_ERR, "Problem updating client configuration\n");
595                return -1;
596        }
597
[0efc182]598        res = update_image_info(dbi, image_id, clonator, compressor,
599                                filesystem, datasize);
600        og_dbi_close(dbi);
601
602        if (res) {
603                syslog(LOG_ERR, "Problem updating image info\n");
604                return -1;
605        }
606
[04ca20e]607        return 0;
608}
609
610static int og_resp_image_restore(json_t *data, struct og_client *cli)
611{
612        struct og_software_legacy soft_legacy;
613        struct og_image_legacy img_legacy;
[cbd9421]614        struct og_computer computer = {};
[04ca20e]615        const char *partition = NULL;
616        const char *image_id = NULL;
617        const char *disk = NULL;
[6e70916]618        const char *msglog;
[04ca20e]619        struct og_dbi *dbi;
[6e70916]620        dbi_result result;
[04ca20e]621        const char *key;
622        json_t *value;
623        int err = 0;
624
625        if (json_typeof(data) != JSON_OBJECT)
626                return -1;
627
628        json_object_foreach(data, key, value) {
629                if (!strcmp(key, "partition"))
630                        err = og_json_parse_string(value, &partition);
631                else if (!strcmp(key, "disk"))
632                        err = og_json_parse_string(value, &disk);
633                else if (!strcmp(key, "image_id"))
634                        err = og_json_parse_string(value, &image_id);
635
636                if (err < 0)
637                        return err;
638        }
639
640        if (!partition || !disk || !image_id) {
641                syslog(LOG_ERR, "malformed response json\n");
642                return -1;
643        }
644
[fe1ce97]645        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]646        if (!dbi) {
647                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
648                       __func__, __LINE__);
649                return -1;
650        }
651
[6e70916]652        result = dbi_conn_queryf(dbi->conn,
653                                 "SELECT idperfilsoft FROM imagenes "
654                                 " WHERE idimagen='%s'", image_id);
655        if (!result) {
[04ca20e]656                og_dbi_close(dbi);
657                syslog(LOG_ERR, "failed to query database\n");
658                return -1;
659        }
[6e70916]660        if (!dbi_result_next_row(result)) {
661                dbi_result_free(result);
[04ca20e]662                og_dbi_close(dbi);
663                syslog(LOG_ERR, "software profile does not exist in database\n");
664                return -1;
665        }
666        snprintf(img_legacy.software_id, sizeof(img_legacy.software_id),
[6e70916]667                 "%d", dbi_result_get_uint(result, "idperfilsoft"));
668        dbi_result_free(result);
[04ca20e]669
[d7e2022]670        err = og_dbi_get_computer_info(dbi, &computer, cli->addr.sin_addr);
671        if (err < 0) {
672                og_dbi_close(dbi);
673                return -1;
674        }
675
676        snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
677                 image_id);
678        snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
679        snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
680        snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
681
[6e70916]682        result = dbi_conn_queryf(dbi->conn,
683                                 "UPDATE ordenadores_particiones"
684                                 "   SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
685                                 "       revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
686                                 "       idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
687                                 " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
688                                 img_legacy.image_id, img_legacy.software_id,
689                                 img_legacy.image_id, img_legacy.software_id,
690                                 soft_legacy.id, img_legacy.disk, img_legacy.part);
691        if (!result) {
692                dbi_conn_error(dbi->conn, &msglog);
693                syslog(LOG_ERR, "failed to update database (%s:%d) %s\n",
694                       __func__, __LINE__, msglog);
695                og_dbi_close(dbi);
[04ca20e]696                return -1;
697        }
[6e70916]698        dbi_result_free(result);
699        og_dbi_close(dbi);
[04ca20e]700
701        return 0;
702}
703
[ac3ce22]704static int og_agent_http_response_code(const char *buf)
705{
706        if (!strncmp(buf, "HTTP/1.0 200 OK", strlen("HTTP/1.0 200 OK"))) {
707                return 200;
708        } else if (!strncmp(buf, "HTTP/1.0 202 Accepted",
709                            strlen("HTTP/1.0 202 Accepted"))) {
710                return 202;
711        } else if (!strncmp(buf, "HTTP/1.0 400 Bad Request",
712                            strlen("HTTP/1.0 400 Bad Request"))) {
713                return 400;
714        } else if (!strncmp(buf, "HTTP/1.0 500 Internal Server Error",
715                            strlen("HTTP/1.0 500 Internal Server Error"))) {
716                return 500;
717        } else if (!strncmp(buf, "HTTP/1.0 503 Service Unavailable",
718                            strlen("HTTP/1.0 503 Service Unavailable"))) {
719                return 503;
[772811e]720        } else if (!strncmp(buf, "HTTP/1.0 103 Early Hints",
721                            strlen("HTTP/1.0 103 Early Hints"))) {
722                return 103;
[ac3ce22]723        }
724
725        return -1;
726}
727
[04ca20e]728int og_agent_state_process_response(struct og_client *cli)
729{
[ac3ce22]730        int ret, err = -1, code;
[04ca20e]731        json_error_t json_err;
[ac3ce22]732        bool success;
[04ca20e]733        json_t *root;
734        char *body;
735
[ac3ce22]736        code = og_agent_http_response_code(cli->buf);
737        switch (code) {
[772811e]738        case 103:
[ac3ce22]739        case 200:
740                ret = 0;
741                success = true;
742                break;
743        case 202:
744                ret = 1;
745                success = true;
746                break;
747        case 400:
748                ret = -1;
749                success = false;
750                syslog(LOG_ERR, "Client %s:%hu reports malformed HTTP request from server\n",
751                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
752                break;
753        case 500:
754                ret = 0;
755                success = false;
756                cli->last_cmd = OG_CMD_UNSPEC;
757                syslog(LOG_ERR, "Client %s:%hu reports failure to process command\n",
758                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
759                /* ... cancel pending actions related to this task for this client here */
760                break;
761        case 503:
762                ret = 1;
763                success = false;
764                syslog(LOG_ERR, "Client %s:%hu is busy to process command\n",
765                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
766                break;
767        default:
768                ret = -1;
769                success = false;
770                syslog(LOG_ERR, "Client %s:%hu reports unknown HTTP response code\n",
771                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
772                break;
[04ca20e]773        }
774
[772811e]775        if (code != 200 && code != 103) {
[ac3ce22]776                og_dbi_update_action(cli->last_cmd_id, success);
[04ca20e]777                cli->last_cmd_id = 0;
[ac3ce22]778                return ret;
[04ca20e]779        }
780
781        if (!cli->content_length) {
[ac3ce22]782                og_dbi_update_action(cli->last_cmd_id, true);
783                cli->last_cmd_id = 0;
[04ca20e]784                cli->last_cmd = OG_CMD_UNSPEC;
785                return 0;
786        }
787
788        body = strstr(cli->buf, "\r\n\r\n") + 4;
789
790        root = json_loads(body, 0, &json_err);
791        if (!root) {
792                syslog(LOG_ERR, "%s:%d: malformed json line %d: %s\n",
793                       __FILE__, __LINE__, json_err.line, json_err.text);
794                return -1;
795        }
796
[772811e]797        if (code == 103) {
798                err = og_resp_early_hints(cli, root);
799                json_decref(root);
800                return err;
801        }
802
[04ca20e]803        switch (cli->last_cmd) {
804        case OG_CMD_PROBE:
805                err = og_resp_probe(cli, root);
806                break;
807        case OG_CMD_SHELL_RUN:
808                err = og_resp_shell_run(cli, root);
809                break;
810        case OG_CMD_HARDWARE:
811                err = og_resp_hardware(root, cli);
812                break;
813        case OG_CMD_SOFTWARE:
814                err = og_resp_software(root, cli);
815                break;
816        case OG_CMD_REFRESH:
817                err = og_resp_refresh(root, cli);
818                break;
819        case OG_CMD_SETUP:
820                err = og_resp_refresh(root, cli);
821                break;
822        case OG_CMD_IMAGE_CREATE:
823                err = og_resp_image_create(root, cli);
824                break;
825        case OG_CMD_IMAGE_RESTORE:
826                err = og_resp_image_restore(root, cli);
827                break;
828        default:
829                err = -1;
830                break;
831        }
832
[0d9d72e]833        json_decref(root);
[ac3ce22]834
835        if (err < 0) {
836                err = 0;
837                success = false;
838                /* ... cancel pending actions related to this task for this client here */
839        }
840
841        og_dbi_update_action(cli->last_cmd_id, success);
842        cli->last_cmd_id = 0;
[04ca20e]843        cli->last_cmd = OG_CMD_UNSPEC;
844
845        return err;
846}
Note: See TracBrowser for help on using the repository browser.