source: ogServer-Git/src/client.c @ ac3ce22

Last change on this file since ac3ce22 was ac3ce22, checked in by Jose M. Guisado <jguisado@…>, 3 years ago

#1064 revisit error handling from ogClient

200 => successful command, run next pending command
202 => successful command in progress, do not run next pending command
403 => server sent a malformed HTTP header, should not ever happen,

close connection (server is buggy?).

500 => client fails to run command, report error and run next pending command
503 => client is busy, report error and do not run next pending command

Anything else, should not ever happen (client is buggy?), close connection with
client.

On error, when processing response from ogClient, do not close the connection,
instead annotate in the database that command was not successful and run next
pending command.

*Only* if client replies status code 500 set last_cmd to UNSPEC so its state is
not BSY as reported by og_client_status function and pending cmds can be
sent.

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