source: ogServer-Git/sources/rest.c @ c46fa3c

Last change on this file since c46fa3c was c46fa3c, checked in by OpenGnSys Support Team <soporte-og@…>, 4 years ago

#980 coding style cleanup

  • Curly braces after function definition
  • use _dbi_ infix for function name
  • Property mode set to 100644
File size: 86.6 KB
RevLine 
[04ca20e]1/*
2 * Copyright (C) 2020 Soleta Networks <info@soleta.eu>
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
6 * Free Software Foundation, version 3.
7 */
8
9#include "ogAdmServer.h"
10#include "dbi.h"
11#include "utils.h"
12#include "list.h"
13#include "rest.h"
14#include "schedule.h"
15#include <ev.h>
16#include <syslog.h>
17#include <sys/ioctl.h>
18#include <ifaddrs.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22#include <jansson.h>
23#include <time.h>
24
25static TRAMA *og_msg_alloc(char *data, unsigned int len)
26{
27        TRAMA *ptrTrama;
28
29        ptrTrama = calloc(1, sizeof(TRAMA));
30        if (!ptrTrama) {
31                syslog(LOG_ERR, "OOM\n");
32                return NULL;
33        }
34
35        initParametros(ptrTrama, len);
36        memcpy(ptrTrama, "@JMMLCAMDJ_MCDJ", LONGITUD_CABECERATRAMA);
37        memcpy(ptrTrama->parametros, data, len);
38        ptrTrama->lonprm = len;
39
40        return ptrTrama;
41}
42
43static void og_msg_free(TRAMA *ptrTrama)
44{
45        free(ptrTrama->parametros);
46        free(ptrTrama);
47}
48
49static bool og_send_cmd(char *ips_array[], int ips_array_len,
50                        const char *state, TRAMA *ptrTrama)
51{
52        int i, idx;
53
54        for (i = 0; i < ips_array_len; i++) {
55                if (clienteDisponible(ips_array[i], &idx)) { // Si el cliente puede recibir comandos
56                        int sock = tbsockets[idx].cli ? tbsockets[idx].cli->io.fd : -1;
57
58                        strcpy(tbsockets[idx].estado, state); // Actualiza el estado del cliente
59                        if (sock >= 0 && !mandaTrama(&sock, ptrTrama)) {
60                                syslog(LOG_ERR, "failed to send response to %s:%s\n",
61                                       ips_array[i], strerror(errno));
62                        }
63                }
64        }
65        return true;
66}
67
68#define OG_REST_PARAM_ADDR                      (1UL << 0)
69#define OG_REST_PARAM_MAC                       (1UL << 1)
70#define OG_REST_PARAM_WOL_TYPE                  (1UL << 2)
71#define OG_REST_PARAM_RUN_CMD                   (1UL << 3)
72#define OG_REST_PARAM_DISK                      (1UL << 4)
73#define OG_REST_PARAM_PARTITION                 (1UL << 5)
74#define OG_REST_PARAM_REPO                      (1UL << 6)
75#define OG_REST_PARAM_NAME                      (1UL << 7)
76#define OG_REST_PARAM_ID                        (1UL << 8)
77#define OG_REST_PARAM_CODE                      (1UL << 9)
78#define OG_REST_PARAM_TYPE                      (1UL << 10)
79#define OG_REST_PARAM_PROFILE                   (1UL << 11)
80#define OG_REST_PARAM_CACHE                     (1UL << 12)
81#define OG_REST_PARAM_CACHE_SIZE                (1UL << 13)
82#define OG_REST_PARAM_PART_0                    (1UL << 14)
83#define OG_REST_PARAM_PART_1                    (1UL << 15)
84#define OG_REST_PARAM_PART_2                    (1UL << 16)
85#define OG_REST_PARAM_PART_3                    (1UL << 17)
86#define OG_REST_PARAM_SYNC_SYNC                 (1UL << 18)
87#define OG_REST_PARAM_SYNC_DIFF                 (1UL << 19)
88#define OG_REST_PARAM_SYNC_REMOVE               (1UL << 20)
89#define OG_REST_PARAM_SYNC_COMPRESS             (1UL << 21)
90#define OG_REST_PARAM_SYNC_CLEANUP              (1UL << 22)
91#define OG_REST_PARAM_SYNC_CACHE                (1UL << 23)
92#define OG_REST_PARAM_SYNC_CLEANUP_CACHE        (1UL << 24)
93#define OG_REST_PARAM_SYNC_REMOVE_DST           (1UL << 25)
94#define OG_REST_PARAM_SYNC_DIFF_ID              (1UL << 26)
95#define OG_REST_PARAM_SYNC_DIFF_NAME            (1UL << 27)
96#define OG_REST_PARAM_SYNC_PATH                 (1UL << 28)
97#define OG_REST_PARAM_SYNC_METHOD               (1UL << 29)
98#define OG_REST_PARAM_ECHO                      (1UL << 30)
99#define OG_REST_PARAM_TASK                      (1UL << 31)
100#define OG_REST_PARAM_TIME_YEARS                (1UL << 32)
101#define OG_REST_PARAM_TIME_MONTHS               (1UL << 33)
102#define OG_REST_PARAM_TIME_WEEKS                (1UL << 34)
103#define OG_REST_PARAM_TIME_WEEK_DAYS            (1UL << 35)
104#define OG_REST_PARAM_TIME_DAYS                 (1UL << 36)
105#define OG_REST_PARAM_TIME_HOURS                (1UL << 37)
106#define OG_REST_PARAM_TIME_AM_PM                (1UL << 38)
107#define OG_REST_PARAM_TIME_MINUTES              (1UL << 39)
108
109static LIST_HEAD(client_list);
110
111void og_client_add(struct og_client *cli)
112{
113        list_add(&cli->list, &client_list);
114}
115
116static struct og_client *og_client_find(const char *ip)
117{
118        struct og_client *client;
119        struct in_addr addr;
120        int res;
121
122        res = inet_aton(ip, &addr);
123        if (!res) {
124                syslog(LOG_ERR, "Invalid IP string: %s\n", ip);
125                return NULL;
126        }
127
128        list_for_each_entry(client, &client_list, list) {
129                if (client->addr.sin_addr.s_addr == addr.s_addr && client->agent) {
130                        return client;
131                }
132        }
133
134        return NULL;
135}
136
137static const char *og_client_status(const struct og_client *cli)
138{
139        if (cli->last_cmd != OG_CMD_UNSPEC)
140                return "BSY";
141
142        switch (cli->status) {
143        case OG_CLIENT_STATUS_BUSY:
144                return "BSY";
145        case OG_CLIENT_STATUS_OGLIVE:
146                return "OPG";
147        default:
148                return "OFF";
149        }
150}
151
152static bool og_msg_params_validate(const struct og_msg_params *params,
153                                   const uint64_t flags)
154{
155        return (params->flags & flags) == flags;
156}
157
158static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
159{
160        unsigned int i;
161        json_t *k;
162
163        if (json_typeof(element) != JSON_ARRAY)
164                return -1;
165
166        for (i = 0; i < json_array_size(element); i++) {
167                k = json_array_get(element, i);
168                if (json_typeof(k) != JSON_STRING)
169                        return -1;
170
171                params->ips_array[params->ips_array_len++] =
172                        json_string_value(k);
173
174                params->flags |= OG_REST_PARAM_ADDR;
175        }
176
177        return 0;
178}
179
180static int og_json_parse_sync_params(json_t *element,
181                                     struct og_msg_params *params)
182{
183        const char *key;
184        json_t *value;
185        int err = 0;
186
187        json_object_foreach(element, key, value) {
188                if (!strcmp(key, "sync")) {
189                        err = og_json_parse_string(value, &params->sync_setup.sync);
190                        params->flags |= OG_REST_PARAM_SYNC_SYNC;
191                } else if (!strcmp(key, "diff")) {
192                        err = og_json_parse_string(value, &params->sync_setup.diff);
193                        params->flags |= OG_REST_PARAM_SYNC_DIFF;
194                } else if (!strcmp(key, "remove")) {
195                        err = og_json_parse_string(value, &params->sync_setup.remove);
196                        params->flags |= OG_REST_PARAM_SYNC_REMOVE;
197                } else if (!strcmp(key, "compress")) {
198                        err = og_json_parse_string(value, &params->sync_setup.compress);
199                        params->flags |= OG_REST_PARAM_SYNC_COMPRESS;
200                } else if (!strcmp(key, "cleanup")) {
201                        err = og_json_parse_string(value, &params->sync_setup.cleanup);
202                        params->flags |= OG_REST_PARAM_SYNC_CLEANUP;
203                } else if (!strcmp(key, "cache")) {
204                        err = og_json_parse_string(value, &params->sync_setup.cache);
205                        params->flags |= OG_REST_PARAM_SYNC_CACHE;
206                } else if (!strcmp(key, "cleanup_cache")) {
207                        err = og_json_parse_string(value, &params->sync_setup.cleanup_cache);
208                        params->flags |= OG_REST_PARAM_SYNC_CLEANUP_CACHE;
209                } else if (!strcmp(key, "remove_dst")) {
210                        err = og_json_parse_string(value, &params->sync_setup.remove_dst);
211                        params->flags |= OG_REST_PARAM_SYNC_REMOVE_DST;
212                } else if (!strcmp(key, "diff_id")) {
213                        err = og_json_parse_string(value, &params->sync_setup.diff_id);
214                        params->flags |= OG_REST_PARAM_SYNC_DIFF_ID;
215                } else if (!strcmp(key, "diff_name")) {
216                        err = og_json_parse_string(value, &params->sync_setup.diff_name);
217                        params->flags |= OG_REST_PARAM_SYNC_DIFF_NAME;
218                } else if (!strcmp(key, "path")) {
219                        err = og_json_parse_string(value, &params->sync_setup.path);
220                        params->flags |= OG_REST_PARAM_SYNC_PATH;
221                } else if (!strcmp(key, "method")) {
222                        err = og_json_parse_string(value, &params->sync_setup.method);
223                        params->flags |= OG_REST_PARAM_SYNC_METHOD;
224                }
225
226                if (err != 0)
227                        return err;
228        }
229        return err;
230}
231
232static int og_json_parse_partition_setup(json_t *element,
233                                         struct og_msg_params *params)
234{
235        unsigned int i;
236        json_t *k;
237
238        if (json_typeof(element) != JSON_ARRAY)
239                return -1;
240
241        for (i = 0; i < json_array_size(element) && i < OG_PARTITION_MAX; ++i) {
242                k = json_array_get(element, i);
243
244                if (json_typeof(k) != JSON_OBJECT)
245                        return -1;
246
247                if (og_json_parse_partition(k, &params->partition_setup[i],
248                                            OG_PARAM_PART_NUMBER |
249                                            OG_PARAM_PART_CODE |
250                                            OG_PARAM_PART_FILESYSTEM |
251                                            OG_PARAM_PART_SIZE |
252                                            OG_PARAM_PART_FORMAT) < 0)
253                        return -1;
254
255                params->flags |= (OG_REST_PARAM_PART_0 << i);
256        }
257        return 0;
258}
259
260static int og_json_parse_time_params(json_t *element,
261                                     struct og_msg_params *params)
262{
263        const char *key;
264        json_t *value;
265        int err = 0;
266
267        json_object_foreach(element, key, value) {
268                if (!strcmp(key, "years")) {
269                        err = og_json_parse_uint(value, &params->time.years);
270                        params->flags |= OG_REST_PARAM_TIME_YEARS;
271                } else if (!strcmp(key, "months")) {
272                        err = og_json_parse_uint(value, &params->time.months);
273                        params->flags |= OG_REST_PARAM_TIME_MONTHS;
274                } else if (!strcmp(key, "weeks")) {
275                        err = og_json_parse_uint(value, &params->time.weeks);
276                        params->flags |= OG_REST_PARAM_TIME_WEEKS;
277                } else if (!strcmp(key, "week_days")) {
278                        err = og_json_parse_uint(value, &params->time.week_days);
279                        params->flags |= OG_REST_PARAM_TIME_WEEK_DAYS;
280                } else if (!strcmp(key, "days")) {
281                        err = og_json_parse_uint(value, &params->time.days);
282                        params->flags |= OG_REST_PARAM_TIME_DAYS;
283                } else if (!strcmp(key, "hours")) {
284                        err = og_json_parse_uint(value, &params->time.hours);
285                        params->flags |= OG_REST_PARAM_TIME_HOURS;
286                } else if (!strcmp(key, "am_pm")) {
287                        err = og_json_parse_uint(value, &params->time.am_pm);
288                        params->flags |= OG_REST_PARAM_TIME_AM_PM;
289                } else if (!strcmp(key, "minutes")) {
290                        err = og_json_parse_uint(value, &params->time.minutes);
291                        params->flags |= OG_REST_PARAM_TIME_MINUTES;
292                }
293                if (err != 0)
294                        return err;
295        }
296
297        return err;
298}
299
300static const char *og_cmd_to_uri[OG_CMD_MAX] = {
301        [OG_CMD_WOL]            = "wol",
302        [OG_CMD_PROBE]          = "probe",
303        [OG_CMD_SHELL_RUN]      = "shell/run",
304        [OG_CMD_SESSION]        = "session",
305        [OG_CMD_POWEROFF]       = "poweroff",
306        [OG_CMD_REFRESH]        = "refresh",
307        [OG_CMD_REBOOT]         = "reboot",
308        [OG_CMD_STOP]           = "stop",
309        [OG_CMD_HARDWARE]       = "hardware",
310        [OG_CMD_SOFTWARE]       = "software",
311        [OG_CMD_IMAGE_CREATE]   = "image/create",
312        [OG_CMD_IMAGE_RESTORE]  = "image/restore",
313        [OG_CMD_SETUP]          = "setup",
314        [OG_CMD_RUN_SCHEDULE]   = "run/schedule",
315};
316
317static bool og_client_is_busy(const struct og_client *cli,
318                              enum og_cmd_type type)
319{
320        switch (type) {
321        case OG_CMD_REBOOT:
322        case OG_CMD_POWEROFF:
323        case OG_CMD_STOP:
324                break;
325        default:
326                if (cli->last_cmd != OG_CMD_UNSPEC)
327                        return true;
328                break;
329        }
330
331        return false;
332}
333
334int og_send_request(enum og_rest_method method, enum og_cmd_type type,
335                    const struct og_msg_params *params,
336                    const json_t *data)
337{
338        const char *content_type = "Content-Type: application/json";
339        char content [OG_MSG_REQUEST_MAXLEN - 700] = {};
340        char buf[OG_MSG_REQUEST_MAXLEN] = {};
341        unsigned int content_length;
342        char method_str[5] = {};
343        struct og_client *cli;
344        const char *uri;
345        unsigned int i;
346        int client_sd;
347
348        if (method == OG_METHOD_GET)
349                snprintf(method_str, 5, "GET");
350        else if (method == OG_METHOD_POST)
351                snprintf(method_str, 5, "POST");
352        else
353                return -1;
354
355        if (!data)
356                content_length = 0;
357        else
358                content_length = json_dumpb(data, content,
359                                            OG_MSG_REQUEST_MAXLEN - 700,
360                                            JSON_COMPACT);
361
362        uri = og_cmd_to_uri[type];
363        snprintf(buf, OG_MSG_REQUEST_MAXLEN,
364                 "%s /%s HTTP/1.1\r\nContent-Length: %d\r\n%s\r\n\r\n%s",
365                 method_str, uri, content_length, content_type, content);
366
367        for (i = 0; i < params->ips_array_len; i++) {
368                cli = og_client_find(params->ips_array[i]);
369                if (!cli)
370                        continue;
371
372                if (og_client_is_busy(cli, type))
373                        continue;
374
375                client_sd = cli->io.fd;
376                if (client_sd < 0) {
377                        syslog(LOG_INFO, "Client %s not conected\n",
378                               params->ips_array[i]);
379                        continue;
380                }
381
382                if (send(client_sd, buf, strlen(buf), 0) < 0)
383                        continue;
384
385                cli->last_cmd = type;
386        }
387
388        return 0;
389}
390
391static int og_cmd_post_clients(json_t *element, struct og_msg_params *params)
392{
393        const char *key;
394        json_t *value;
395        int err = 0;
396
397        if (json_typeof(element) != JSON_OBJECT)
398                return -1;
399
400        json_object_foreach(element, key, value) {
401                if (!strcmp(key, "clients"))
402                        err = og_json_parse_clients(value, params);
403
404                if (err < 0)
405                        break;
406        }
407
408        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
409                return -1;
410
411        return og_send_request(OG_METHOD_POST, OG_CMD_PROBE, params, NULL);
412}
413
414struct og_buffer {
415        char    *data;
416        int     len;
417};
418
419static int og_json_dump_clients(const char *buffer, size_t size, void *data)
420{
421        struct og_buffer *og_buffer = (struct og_buffer *)data;
422
423        memcpy(og_buffer->data + og_buffer->len, buffer, size);
424        og_buffer->len += size;
425
426        return 0;
427}
428
429static int og_cmd_get_clients(json_t *element, struct og_msg_params *params,
430                              char *buffer_reply)
431{
432        json_t *root, *array, *addr, *state, *object;
433        struct og_client *client;
434        struct og_buffer og_buffer = {
435                .data   = buffer_reply,
436        };
437
438        array = json_array();
439        if (!array)
440                return -1;
441
442        list_for_each_entry(client, &client_list, list) {
443                if (!client->agent)
444                        continue;
445
446                object = json_object();
447                if (!object) {
448                        json_decref(array);
449                        return -1;
450                }
451                addr = json_string(inet_ntoa(client->addr.sin_addr));
452                if (!addr) {
453                        json_decref(object);
454                        json_decref(array);
455                        return -1;
456                }
457                json_object_set_new(object, "addr", addr);
458                state = json_string(og_client_status(client));
459                if (!state) {
460                        json_decref(object);
461                        json_decref(array);
462                        return -1;
463                }
464                json_object_set_new(object, "state", state);
465                json_array_append_new(array, object);
466        }
467        root = json_pack("{s:o}", "clients", array);
468        if (!root) {
469                json_decref(array);
470                return -1;
471        }
472
473        json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
474        json_decref(root);
475
476        return 0;
477}
478
479static int og_json_parse_target(json_t *element, struct og_msg_params *params)
480{
481        const char *key;
482        json_t *value;
483
484        if (json_typeof(element) != JSON_OBJECT) {
485                return -1;
486        }
487
488        json_object_foreach(element, key, value) {
489                if (!strcmp(key, "addr")) {
490                        if (json_typeof(value) != JSON_STRING)
491                                return -1;
492
493                        params->ips_array[params->ips_array_len] =
494                                json_string_value(value);
495
496                        params->flags |= OG_REST_PARAM_ADDR;
497                } else if (!strcmp(key, "mac")) {
498                        if (json_typeof(value) != JSON_STRING)
499                                return -1;
500
501                        params->mac_array[params->ips_array_len] =
502                                json_string_value(value);
503
504                        params->flags |= OG_REST_PARAM_MAC;
505                }
506        }
507
508        return 0;
509}
510
511static int og_json_parse_targets(json_t *element, struct og_msg_params *params)
512{
513        unsigned int i;
514        json_t *k;
515        int err;
516
517        if (json_typeof(element) != JSON_ARRAY)
518                return -1;
519
520        for (i = 0; i < json_array_size(element); i++) {
521                k = json_array_get(element, i);
522
523                if (json_typeof(k) != JSON_OBJECT)
524                        return -1;
525
526                err = og_json_parse_target(k, params);
527                if (err < 0)
528                        return err;
529
530                params->ips_array_len++;
531        }
532        return 0;
533}
534
535static int og_json_parse_type(json_t *element, struct og_msg_params *params)
536{
537        const char *type;
538
539        if (json_typeof(element) != JSON_STRING)
540                return -1;
541
542        params->wol_type = json_string_value(element);
543
544        type = json_string_value(element);
545        if (!strcmp(type, "unicast"))
546                params->wol_type = "2";
547        else if (!strcmp(type, "broadcast"))
548                params->wol_type = "1";
549
550        params->flags |= OG_REST_PARAM_WOL_TYPE;
551
552        return 0;
553}
554
555static int og_cmd_wol(json_t *element, struct og_msg_params *params)
556{
557        const char *key;
558        json_t *value;
559        int err = 0;
560
561        if (json_typeof(element) != JSON_OBJECT)
562                return -1;
563
564        json_object_foreach(element, key, value) {
565                if (!strcmp(key, "clients")) {
566                        err = og_json_parse_targets(value, params);
567                } else if (!strcmp(key, "type")) {
568                        err = og_json_parse_type(value, params);
569                }
570
571                if (err < 0)
572                        break;
573        }
574
575        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
576                                            OG_REST_PARAM_MAC |
577                                            OG_REST_PARAM_WOL_TYPE))
578                return -1;
579
580        if (!Levanta((char **)params->ips_array, (char **)params->mac_array,
581                     params->ips_array_len, (char *)params->wol_type))
582                return -1;
583
584        return 0;
585}
586
587static int og_json_parse_run(json_t *element, struct og_msg_params *params)
588{
589        if (json_typeof(element) != JSON_STRING)
590                return -1;
591
592        snprintf(params->run_cmd, sizeof(params->run_cmd), "%s",
593                 json_string_value(element));
594
595        params->flags |= OG_REST_PARAM_RUN_CMD;
596
597        return 0;
598}
599
600static int og_cmd_run_post(json_t *element, struct og_msg_params *params)
601{
602        json_t *value, *clients;
603        const char *key;
604        unsigned int i;
605        int err = 0;
606
607        if (json_typeof(element) != JSON_OBJECT)
608                return -1;
609
610        json_object_foreach(element, key, value) {
611                if (!strcmp(key, "clients"))
612                        err = og_json_parse_clients(value, params);
613                else if (!strcmp(key, "run"))
614                        err = og_json_parse_run(value, params);
615                else if (!strcmp(key, "echo")) {
616                        err = og_json_parse_bool(value, &params->echo);
617                        params->flags |= OG_REST_PARAM_ECHO;
618                }
619
620                if (err < 0)
621                        break;
622        }
623
624        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
625                                            OG_REST_PARAM_RUN_CMD |
626                                            OG_REST_PARAM_ECHO))
627                return -1;
628
629        clients = json_copy(element);
630        json_object_del(clients, "clients");
631
632        err = og_send_request(OG_METHOD_POST, OG_CMD_SHELL_RUN, params, clients);
633        if (err < 0)
634                return err;
635
636        for (i = 0; i < params->ips_array_len; i++) {
637                char filename[4096];
638                FILE *f;
639
640                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
641                f = fopen(filename, "wt");
642                fclose(f);
643        }
644
645        return 0;
646}
647
648static int og_cmd_run_get(json_t *element, struct og_msg_params *params,
649                          char *buffer_reply)
650{
651        struct og_buffer og_buffer = {
652                .data   = buffer_reply,
653        };
654        json_t *root, *value, *array;
655        const char *key;
656        unsigned int i;
657        int err = 0;
658
659        if (json_typeof(element) != JSON_OBJECT)
660                return -1;
661
662        json_object_foreach(element, key, value) {
663                if (!strcmp(key, "clients"))
664                        err = og_json_parse_clients(value, params);
665
666                if (err < 0)
667                        return err;
668        }
669
670        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
671                return -1;
672
673        array = json_array();
674        if (!array)
675                return -1;
676
677        for (i = 0; i < params->ips_array_len; i++) {
678                json_t *object, *output, *addr;
679                char data[4096] = {};
680                char filename[4096];
681                int fd, numbytes;
682
683                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
684
685                fd = open(filename, O_RDONLY);
686                if (!fd)
687                        return -1;
688
689                numbytes = read(fd, data, sizeof(data));
690                if (numbytes < 0) {
691                        close(fd);
692                        return -1;
693                }
694                data[sizeof(data) - 1] = '\0';
695                close(fd);
696
697                object = json_object();
698                if (!object) {
699                        json_decref(array);
700                        return -1;
701                }
702                addr = json_string(params->ips_array[i]);
703                if (!addr) {
704                        json_decref(object);
705                        json_decref(array);
706                        return -1;
707                }
708                json_object_set_new(object, "addr", addr);
709
710                output = json_string(data);
711                if (!output) {
712                        json_decref(object);
713                        json_decref(array);
714                        return -1;
715                }
716                json_object_set_new(object, "output", output);
717
718                json_array_append_new(array, object);
719        }
720
721        root = json_pack("{s:o}", "clients", array);
722        if (!root)
723                return -1;
724
725        json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
726        json_decref(root);
727
728        return 0;
729}
730
731static int og_cmd_session(json_t *element, struct og_msg_params *params)
732{
733        json_t *clients, *value;
734        const char *key;
735        int err = 0;
736
737        if (json_typeof(element) != JSON_OBJECT)
738                return -1;
739
740        json_object_foreach(element, key, value) {
741                if (!strcmp(key, "clients")) {
742                        err = og_json_parse_clients(value, params);
743                } else if (!strcmp(key, "disk")) {
744                        err = og_json_parse_string(value, &params->disk);
745                        params->flags |= OG_REST_PARAM_DISK;
746                } else if (!strcmp(key, "partition")) {
747                        err = og_json_parse_string(value, &params->partition);
748                        params->flags |= OG_REST_PARAM_PARTITION;
749                }
750
751                if (err < 0)
752                        return err;
753        }
754
755        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
756                                            OG_REST_PARAM_DISK |
757                                            OG_REST_PARAM_PARTITION))
758                return -1;
759
760        clients = json_copy(element);
761        json_object_del(clients, "clients");
762
763        return og_send_request(OG_METHOD_POST, OG_CMD_SESSION, params, clients);
764}
765
766static int og_cmd_poweroff(json_t *element, struct og_msg_params *params)
767{
768        const char *key;
769        json_t *value;
770        int err = 0;
771
772        if (json_typeof(element) != JSON_OBJECT)
773                return -1;
774
775        json_object_foreach(element, key, value) {
776                if (!strcmp(key, "clients"))
777                        err = og_json_parse_clients(value, params);
778
779                if (err < 0)
780                        break;
781        }
782
783        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
784                return -1;
785
786        return og_send_request(OG_METHOD_POST, OG_CMD_POWEROFF, params, NULL);
787}
788
789static int og_cmd_refresh(json_t *element, struct og_msg_params *params)
790{
791        const char *key;
792        json_t *value;
793        int err = 0;
794
795        if (json_typeof(element) != JSON_OBJECT)
796                return -1;
797
798        json_object_foreach(element, key, value) {
799                if (!strcmp(key, "clients"))
800                        err = og_json_parse_clients(value, params);
801
802                if (err < 0)
803                        break;
804        }
805
806        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
807                return -1;
808
809        return og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, params, NULL);
810}
811
812static int og_cmd_reboot(json_t *element, struct og_msg_params *params)
813{
814        const char *key;
815        json_t *value;
816        int err = 0;
817
818        if (json_typeof(element) != JSON_OBJECT)
819                return -1;
820
821        json_object_foreach(element, key, value) {
822                if (!strcmp(key, "clients"))
823                        err = og_json_parse_clients(value, params);
824
825                if (err < 0)
826                        break;
827        }
828
829        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
830                return -1;
831
832        return og_send_request(OG_METHOD_POST, OG_CMD_REBOOT, params, NULL);
833}
834
835static int og_cmd_stop(json_t *element, struct og_msg_params *params)
836{
837        const char *key;
838        json_t *value;
839        int err = 0;
840
841        if (json_typeof(element) != JSON_OBJECT)
842                return -1;
843
844        json_object_foreach(element, key, value) {
845                if (!strcmp(key, "clients"))
846                        err = og_json_parse_clients(value, params);
847
848                if (err < 0)
849                        break;
850        }
851
852        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
853                return -1;
854
855        return og_send_request(OG_METHOD_POST, OG_CMD_STOP, params, NULL);
856}
857
858static int og_cmd_hardware(json_t *element, struct og_msg_params *params)
859{
860        const char *key;
861        json_t *value;
862        int err = 0;
863
864        if (json_typeof(element) != JSON_OBJECT)
865                return -1;
866
867        json_object_foreach(element, key, value) {
868                if (!strcmp(key, "clients"))
869                        err = og_json_parse_clients(value, params);
870
871                if (err < 0)
872                        break;
873        }
874
875        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
876                return -1;
877
878        return og_send_request(OG_METHOD_GET, OG_CMD_HARDWARE, params, NULL);
879}
880
881static int og_cmd_software(json_t *element, struct og_msg_params *params)
882{
883        json_t *clients, *value;
884        const char *key;
885        int err = 0;
886
887        if (json_typeof(element) != JSON_OBJECT)
888                return -1;
889
890        json_object_foreach(element, key, value) {
891                if (!strcmp(key, "clients"))
892                        err = og_json_parse_clients(value, params);
893                else if (!strcmp(key, "disk")) {
894                        err = og_json_parse_string(value, &params->disk);
895                        params->flags |= OG_REST_PARAM_DISK;
896                }
897                else if (!strcmp(key, "partition")) {
898                        err = og_json_parse_string(value, &params->partition);
899                        params->flags |= OG_REST_PARAM_PARTITION;
900                }
901
902                if (err < 0)
903                        break;
904        }
905
906        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
907                                            OG_REST_PARAM_DISK |
908                                            OG_REST_PARAM_PARTITION))
909                return -1;
910
911        clients = json_copy(element);
912        json_object_del(clients, "clients");
913
914        return og_send_request(OG_METHOD_POST, OG_CMD_SOFTWARE, params, clients);
915}
916
917static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
918{
919        json_t *value, *clients;
920        const char *key;
921        int err = 0;
922
923        if (json_typeof(element) != JSON_OBJECT)
924                return -1;
925
926        json_object_foreach(element, key, value) {
927                if (!strcmp(key, "disk")) {
928                        err = og_json_parse_string(value, &params->disk);
929                        params->flags |= OG_REST_PARAM_DISK;
930                } else if (!strcmp(key, "partition")) {
931                        err = og_json_parse_string(value, &params->partition);
932                        params->flags |= OG_REST_PARAM_PARTITION;
933                } else if (!strcmp(key, "name")) {
934                        err = og_json_parse_string(value, &params->name);
935                        params->flags |= OG_REST_PARAM_NAME;
936                } else if (!strcmp(key, "repository")) {
937                        err = og_json_parse_string(value, &params->repository);
938                        params->flags |= OG_REST_PARAM_REPO;
939                } else if (!strcmp(key, "clients")) {
940                        err = og_json_parse_clients(value, params);
941                } else if (!strcmp(key, "id")) {
942                        err = og_json_parse_string(value, &params->id);
943                        params->flags |= OG_REST_PARAM_ID;
944                } else if (!strcmp(key, "code")) {
945                        err = og_json_parse_string(value, &params->code);
946                        params->flags |= OG_REST_PARAM_CODE;
947                }
948
949                if (err < 0)
950                        break;
951        }
952
953        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
954                                            OG_REST_PARAM_DISK |
955                                            OG_REST_PARAM_PARTITION |
956                                            OG_REST_PARAM_CODE |
957                                            OG_REST_PARAM_ID |
958                                            OG_REST_PARAM_NAME |
959                                            OG_REST_PARAM_REPO))
960                return -1;
961
962        clients = json_copy(element);
963        json_object_del(clients, "clients");
964
965        return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_CREATE, params,
966                               clients);
967}
968
969static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
970{
971        json_t *clients, *value;
972        const char *key;
973        int err = 0;
974
975        if (json_typeof(element) != JSON_OBJECT)
976                return -1;
977
978        json_object_foreach(element, key, value) {
979                if (!strcmp(key, "disk")) {
980                        err = og_json_parse_string(value, &params->disk);
981                        params->flags |= OG_REST_PARAM_DISK;
982                } else if (!strcmp(key, "partition")) {
983                        err = og_json_parse_string(value, &params->partition);
984                        params->flags |= OG_REST_PARAM_PARTITION;
985                } else if (!strcmp(key, "name")) {
986                        err = og_json_parse_string(value, &params->name);
987                        params->flags |= OG_REST_PARAM_NAME;
988                } else if (!strcmp(key, "repository")) {
989                        err = og_json_parse_string(value, &params->repository);
990                        params->flags |= OG_REST_PARAM_REPO;
991                } else if (!strcmp(key, "clients")) {
992                        err = og_json_parse_clients(value, params);
993                } else if (!strcmp(key, "type")) {
994                        err = og_json_parse_string(value, &params->type);
995                        params->flags |= OG_REST_PARAM_TYPE;
996                } else if (!strcmp(key, "profile")) {
997                        err = og_json_parse_string(value, &params->profile);
998                        params->flags |= OG_REST_PARAM_PROFILE;
999                } else if (!strcmp(key, "id")) {
1000                        err = og_json_parse_string(value, &params->id);
1001                        params->flags |= OG_REST_PARAM_ID;
1002                }
1003
1004                if (err < 0)
1005                        break;
1006        }
1007
1008        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1009                                            OG_REST_PARAM_DISK |
1010                                            OG_REST_PARAM_PARTITION |
1011                                            OG_REST_PARAM_NAME |
1012                                            OG_REST_PARAM_REPO |
1013                                            OG_REST_PARAM_TYPE |
1014                                            OG_REST_PARAM_PROFILE |
1015                                            OG_REST_PARAM_ID))
1016                return -1;
1017
1018        clients = json_copy(element);
1019        json_object_del(clients, "clients");
1020
1021        return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, params,
1022                               clients);
1023}
1024
1025static int og_cmd_setup(json_t *element, struct og_msg_params *params)
1026{
1027        json_t *value, *clients;
1028        const char *key;
1029        int err = 0;
1030
1031        if (json_typeof(element) != JSON_OBJECT)
1032                return -1;
1033
1034        json_object_foreach(element, key, value) {
1035                if (!strcmp(key, "clients")) {
1036                        err = og_json_parse_clients(value, params);
1037                } else if (!strcmp(key, "disk")) {
1038                        err = og_json_parse_string(value, &params->disk);
1039                        params->flags |= OG_REST_PARAM_DISK;
1040                } else if (!strcmp(key, "cache")) {
1041                        err = og_json_parse_string(value, &params->cache);
1042                        params->flags |= OG_REST_PARAM_CACHE;
1043                } else if (!strcmp(key, "cache_size")) {
1044                        err = og_json_parse_string(value, &params->cache_size);
1045                        params->flags |= OG_REST_PARAM_CACHE_SIZE;
1046                } else if (!strcmp(key, "partition_setup")) {
1047                        err = og_json_parse_partition_setup(value, params);
1048                }
1049
1050                if (err < 0)
1051                        break;
1052        }
1053
1054        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1055                                            OG_REST_PARAM_DISK |
1056                                            OG_REST_PARAM_CACHE |
1057                                            OG_REST_PARAM_CACHE_SIZE |
1058                                            OG_REST_PARAM_PART_0 |
1059                                            OG_REST_PARAM_PART_1 |
1060                                            OG_REST_PARAM_PART_2 |
1061                                            OG_REST_PARAM_PART_3))
1062                return -1;
1063
1064        clients = json_copy(element);
1065        json_object_del(clients, "clients");
1066
1067        return og_send_request(OG_METHOD_POST, OG_CMD_SETUP, params, clients);
1068}
1069
1070static int og_cmd_run_schedule(json_t *element, struct og_msg_params *params)
1071{
1072        const char *key;
1073        json_t *value;
1074        int err = 0;
1075
1076        json_object_foreach(element, key, value) {
1077                if (!strcmp(key, "clients"))
1078                        err = og_json_parse_clients(value, params);
1079
1080                if (err < 0)
1081                        break;
1082        }
1083
1084        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1085                return -1;
1086
1087        return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params,
1088                               NULL);
1089}
1090
1091static int og_cmd_create_basic_image(json_t *element, struct og_msg_params *params)
1092{
1093        char buf[4096] = {};
1094        int err = 0, len;
1095        const char *key;
1096        json_t *value;
1097        TRAMA *msg;
1098
1099        if (json_typeof(element) != JSON_OBJECT)
1100                return -1;
1101
1102        json_object_foreach(element, key, value) {
1103                if (!strcmp(key, "clients")) {
1104                        err = og_json_parse_clients(value, params);
1105                } else if (!strcmp(key, "disk")) {
1106                        err = og_json_parse_string(value, &params->disk);
1107                        params->flags |= OG_REST_PARAM_DISK;
1108                } else if (!strcmp(key, "partition")) {
1109                        err = og_json_parse_string(value, &params->partition);
1110                        params->flags |= OG_REST_PARAM_PARTITION;
1111                } else if (!strcmp(key, "code")) {
1112                        err = og_json_parse_string(value, &params->code);
1113                        params->flags |= OG_REST_PARAM_CODE;
1114                } else if (!strcmp(key, "id")) {
1115                        err = og_json_parse_string(value, &params->id);
1116                        params->flags |= OG_REST_PARAM_ID;
1117                } else if (!strcmp(key, "name")) {
1118                        err = og_json_parse_string(value, &params->name);
1119                        params->flags |= OG_REST_PARAM_NAME;
1120                } else if (!strcmp(key, "repository")) {
1121                        err = og_json_parse_string(value, &params->repository);
1122                        params->flags |= OG_REST_PARAM_REPO;
1123                } else if (!strcmp(key, "sync_params")) {
1124                        err = og_json_parse_sync_params(value, params);
1125                }
1126
1127                if (err < 0)
1128                        break;
1129        }
1130
1131        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1132                                            OG_REST_PARAM_DISK |
1133                                            OG_REST_PARAM_PARTITION |
1134                                            OG_REST_PARAM_CODE |
1135                                            OG_REST_PARAM_ID |
1136                                            OG_REST_PARAM_NAME |
1137                                            OG_REST_PARAM_REPO |
1138                                            OG_REST_PARAM_SYNC_SYNC |
1139                                            OG_REST_PARAM_SYNC_DIFF |
1140                                            OG_REST_PARAM_SYNC_REMOVE |
1141                                            OG_REST_PARAM_SYNC_COMPRESS |
1142                                            OG_REST_PARAM_SYNC_CLEANUP |
1143                                            OG_REST_PARAM_SYNC_CACHE |
1144                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
1145                                            OG_REST_PARAM_SYNC_REMOVE_DST))
1146                return -1;
1147
1148        len = snprintf(buf, sizeof(buf),
1149                       "nfn=CrearImagenBasica\rdsk=%s\rpar=%s\rcpt=%s\ridi=%s\r"
1150                       "nci=%s\ripr=%s\rrti=\rmsy=%s\rwhl=%s\reli=%s\rcmp=%s\rbpi=%s\r"
1151                       "cpc=%s\rbpc=%s\rnba=%s\r",
1152                       params->disk, params->partition, params->code, params->id,
1153                       params->name, params->repository, params->sync_setup.sync,
1154                       params->sync_setup.diff, params->sync_setup.remove,
1155                       params->sync_setup.compress, params->sync_setup.cleanup,
1156                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
1157                       params->sync_setup.remove_dst);
1158
1159        msg = og_msg_alloc(buf, len);
1160        if (!msg)
1161                return -1;
1162
1163        og_send_cmd((char **)params->ips_array, params->ips_array_len,
1164                    CLIENTE_OCUPADO, msg);
1165
1166        og_msg_free(msg);
1167
1168        return 0;
1169}
1170
1171static int og_cmd_create_incremental_image(json_t *element, struct og_msg_params *params)
1172{
1173        char buf[4096] = {};
1174        int err = 0, len;
1175        const char *key;
1176        json_t *value;
1177        TRAMA *msg;
1178
1179        if (json_typeof(element) != JSON_OBJECT)
1180                return -1;
1181
1182        json_object_foreach(element, key, value) {
1183                if (!strcmp(key, "clients"))
1184                        err = og_json_parse_clients(value, params);
1185                else if (!strcmp(key, "disk")) {
1186                        err = og_json_parse_string(value, &params->disk);
1187                        params->flags |= OG_REST_PARAM_DISK;
1188                } else if (!strcmp(key, "partition")) {
1189                        err = og_json_parse_string(value, &params->partition);
1190                        params->flags |= OG_REST_PARAM_PARTITION;
1191                } else if (!strcmp(key, "id")) {
1192                        err = og_json_parse_string(value, &params->id);
1193                        params->flags |= OG_REST_PARAM_ID;
1194                } else if (!strcmp(key, "name")) {
1195                        err = og_json_parse_string(value, &params->name);
1196                        params->flags |= OG_REST_PARAM_NAME;
1197                } else if (!strcmp(key, "repository")) {
1198                        err = og_json_parse_string(value, &params->repository);
1199                        params->flags |= OG_REST_PARAM_REPO;
1200                } else if (!strcmp(key, "sync_params")) {
1201                        err = og_json_parse_sync_params(value, params);
1202                }
1203
1204                if (err < 0)
1205                        break;
1206        }
1207
1208        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1209                                            OG_REST_PARAM_DISK |
1210                                            OG_REST_PARAM_PARTITION |
1211                                            OG_REST_PARAM_ID |
1212                                            OG_REST_PARAM_NAME |
1213                                            OG_REST_PARAM_REPO |
1214                                            OG_REST_PARAM_SYNC_SYNC |
1215                                            OG_REST_PARAM_SYNC_PATH |
1216                                            OG_REST_PARAM_SYNC_DIFF |
1217                                            OG_REST_PARAM_SYNC_DIFF_ID |
1218                                            OG_REST_PARAM_SYNC_DIFF_NAME |
1219                                            OG_REST_PARAM_SYNC_REMOVE |
1220                                            OG_REST_PARAM_SYNC_COMPRESS |
1221                                            OG_REST_PARAM_SYNC_CLEANUP |
1222                                            OG_REST_PARAM_SYNC_CACHE |
1223                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
1224                                            OG_REST_PARAM_SYNC_REMOVE_DST))
1225                return -1;
1226
1227        len = snprintf(buf, sizeof(buf),
1228                       "nfn=CrearSoftIncremental\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
1229                       "rti=%s\ripr=%s\ridf=%s\rncf=%s\rmsy=%s\rwhl=%s\reli=%s\rcmp=%s\r"
1230                       "bpi=%s\rcpc=%s\rbpc=%s\rnba=%s\r",
1231                       params->disk, params->partition, params->id, params->name,
1232                       params->sync_setup.path, params->repository, params->sync_setup.diff_id,
1233                       params->sync_setup.diff_name, params->sync_setup.sync,
1234                       params->sync_setup.diff, params->sync_setup.remove_dst,
1235                       params->sync_setup.compress, params->sync_setup.cleanup,
1236                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
1237                       params->sync_setup.remove_dst);
1238
1239        msg = og_msg_alloc(buf, len);
1240        if (!msg)
1241                return -1;
1242
1243        og_send_cmd((char **)params->ips_array, params->ips_array_len,
1244                    CLIENTE_OCUPADO, msg);
1245
1246        og_msg_free(msg);
1247
1248        return 0;
1249}
1250
1251static int og_cmd_restore_basic_image(json_t *element, struct og_msg_params *params)
1252{
1253        char buf[4096] = {};
1254        int err = 0, len;
1255        const char *key;
1256        json_t *value;
1257        TRAMA *msg;
1258
1259        if (json_typeof(element) != JSON_OBJECT)
1260                return -1;
1261
1262        json_object_foreach(element, key, value) {
1263                if (!strcmp(key, "clients")) {
1264                        err = og_json_parse_clients(value, params);
1265                } else if (!strcmp(key, "disk")) {
1266                        err = og_json_parse_string(value, &params->disk);
1267                        params->flags |= OG_REST_PARAM_DISK;
1268                } else if (!strcmp(key, "partition")) {
1269                        err = og_json_parse_string(value, &params->partition);
1270                        params->flags |= OG_REST_PARAM_PARTITION;
1271                } else if (!strcmp(key, "id")) {
1272                        err = og_json_parse_string(value, &params->id);
1273                        params->flags |= OG_REST_PARAM_ID;
1274                } else if (!strcmp(key, "name")) {
1275                        err = og_json_parse_string(value, &params->name);
1276                        params->flags |= OG_REST_PARAM_NAME;
1277                } else if (!strcmp(key, "repository")) {
1278                        err = og_json_parse_string(value, &params->repository);
1279                        params->flags |= OG_REST_PARAM_REPO;
1280                } else if (!strcmp(key, "profile")) {
1281                        err = og_json_parse_string(value, &params->profile);
1282                        params->flags |= OG_REST_PARAM_PROFILE;
1283                } else if (!strcmp(key, "type")) {
1284                        err = og_json_parse_string(value, &params->type);
1285                        params->flags |= OG_REST_PARAM_TYPE;
1286                } else if (!strcmp(key, "sync_params")) {
1287                        err = og_json_parse_sync_params(value, params);
1288                }
1289
1290                if (err < 0)
1291                        break;
1292        }
1293
1294        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1295                                            OG_REST_PARAM_DISK |
1296                                            OG_REST_PARAM_PARTITION |
1297                                            OG_REST_PARAM_ID |
1298                                            OG_REST_PARAM_NAME |
1299                                            OG_REST_PARAM_REPO |
1300                                            OG_REST_PARAM_PROFILE |
1301                                            OG_REST_PARAM_TYPE |
1302                                            OG_REST_PARAM_SYNC_PATH |
1303                                            OG_REST_PARAM_SYNC_METHOD |
1304                                            OG_REST_PARAM_SYNC_SYNC |
1305                                            OG_REST_PARAM_SYNC_DIFF |
1306                                            OG_REST_PARAM_SYNC_REMOVE |
1307                                            OG_REST_PARAM_SYNC_COMPRESS |
1308                                            OG_REST_PARAM_SYNC_CLEANUP |
1309                                            OG_REST_PARAM_SYNC_CACHE |
1310                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
1311                                            OG_REST_PARAM_SYNC_REMOVE_DST))
1312                return -1;
1313
1314        len = snprintf(buf, sizeof(buf),
1315                       "nfn=RestaurarImagenBasica\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
1316                           "ipr=%s\rifs=%s\rrti=%s\rmet=%s\rmsy=%s\rtpt=%s\rwhl=%s\r"
1317                           "eli=%s\rcmp=%s\rbpi=%s\rcpc=%s\rbpc=%s\rnba=%s\r",
1318                       params->disk, params->partition, params->id, params->name,
1319                           params->repository, params->profile, params->sync_setup.path,
1320                           params->sync_setup.method, params->sync_setup.sync, params->type,
1321                           params->sync_setup.diff, params->sync_setup.remove,
1322                       params->sync_setup.compress, params->sync_setup.cleanup,
1323                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
1324                       params->sync_setup.remove_dst);
1325
1326        msg = og_msg_alloc(buf, len);
1327        if (!msg)
1328                return -1;
1329
1330        og_send_cmd((char **)params->ips_array, params->ips_array_len,
1331                    CLIENTE_OCUPADO, msg);
1332
1333        og_msg_free(msg);
1334
1335        return 0;
1336}
1337
1338static int og_cmd_restore_incremental_image(json_t *element, struct og_msg_params *params)
1339{
1340        char buf[4096] = {};
1341        int err = 0, len;
1342        const char *key;
1343        json_t *value;
1344        TRAMA *msg;
1345
1346        if (json_typeof(element) != JSON_OBJECT)
1347                return -1;
1348
1349        json_object_foreach(element, key, value) {
1350                if (!strcmp(key, "clients")) {
1351                        err = og_json_parse_clients(value, params);
1352                } else if (!strcmp(key, "disk")) {
1353                        err = og_json_parse_string(value, &params->disk);
1354                        params->flags |= OG_REST_PARAM_DISK;
1355                } else if (!strcmp(key, "partition")) {
1356                        err = og_json_parse_string(value, &params->partition);
1357                        params->flags |= OG_REST_PARAM_PARTITION;
1358                } else if (!strcmp(key, "id")) {
1359                        err = og_json_parse_string(value, &params->id);
1360                        params->flags |= OG_REST_PARAM_ID;
1361                } else if (!strcmp(key, "name")) {
1362                        err = og_json_parse_string(value, &params->name);
1363                        params->flags |= OG_REST_PARAM_NAME;
1364                } else if (!strcmp(key, "repository")) {
1365                        err = og_json_parse_string(value, &params->repository);
1366                        params->flags |= OG_REST_PARAM_REPO;
1367                } else if (!strcmp(key, "profile")) {
1368                        err = og_json_parse_string(value, &params->profile);
1369                        params->flags |= OG_REST_PARAM_PROFILE;
1370                } else if (!strcmp(key, "type")) {
1371                        err = og_json_parse_string(value, &params->type);
1372                        params->flags |= OG_REST_PARAM_TYPE;
1373                } else if (!strcmp(key, "sync_params")) {
1374                        err = og_json_parse_sync_params(value, params);
1375                }
1376
1377                if (err < 0)
1378                        break;
1379        }
1380
1381        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1382                                            OG_REST_PARAM_DISK |
1383                                            OG_REST_PARAM_PARTITION |
1384                                            OG_REST_PARAM_ID |
1385                                            OG_REST_PARAM_NAME |
1386                                            OG_REST_PARAM_REPO |
1387                                            OG_REST_PARAM_PROFILE |
1388                                            OG_REST_PARAM_TYPE |
1389                                            OG_REST_PARAM_SYNC_DIFF_ID |
1390                                            OG_REST_PARAM_SYNC_DIFF_NAME |
1391                                            OG_REST_PARAM_SYNC_PATH |
1392                                            OG_REST_PARAM_SYNC_METHOD |
1393                                            OG_REST_PARAM_SYNC_SYNC |
1394                                            OG_REST_PARAM_SYNC_DIFF |
1395                                            OG_REST_PARAM_SYNC_REMOVE |
1396                                            OG_REST_PARAM_SYNC_COMPRESS |
1397                                            OG_REST_PARAM_SYNC_CLEANUP |
1398                                            OG_REST_PARAM_SYNC_CACHE |
1399                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
1400                                            OG_REST_PARAM_SYNC_REMOVE_DST))
1401                return -1;
1402
1403        len = snprintf(buf, sizeof(buf),
1404                       "nfn=RestaurarSoftIncremental\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
1405                           "ipr=%s\rifs=%s\ridf=%s\rncf=%s\rrti=%s\rmet=%s\rmsy=%s\r"
1406                           "tpt=%s\rwhl=%s\reli=%s\rcmp=%s\rbpi=%s\rcpc=%s\rbpc=%s\r"
1407                           "nba=%s\r",
1408                       params->disk, params->partition, params->id, params->name,
1409                           params->repository, params->profile, params->sync_setup.diff_id,
1410                           params->sync_setup.diff_name, params->sync_setup.path,
1411                           params->sync_setup.method, params->sync_setup.sync, params->type,
1412                           params->sync_setup.diff, params->sync_setup.remove,
1413                       params->sync_setup.compress, params->sync_setup.cleanup,
1414                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
1415                       params->sync_setup.remove_dst);
1416
1417        msg = og_msg_alloc(buf, len);
1418        if (!msg)
1419                return -1;
1420
1421        og_send_cmd((char **)params->ips_array, params->ips_array_len,
1422                    CLIENTE_OCUPADO, msg);
1423
1424        og_msg_free(msg);
1425
1426        return 0;
1427}
1428
1429static LIST_HEAD(cmd_list);
1430
1431const struct og_cmd *og_cmd_find(const char *client_ip)
1432{
1433        struct og_cmd *cmd, *next;
1434
1435        list_for_each_entry_safe(cmd, next, &cmd_list, list) {
1436                if (strcmp(cmd->ip, client_ip))
1437                        continue;
1438
1439                list_del(&cmd->list);
1440                return cmd;
1441        }
1442
1443        return NULL;
1444}
1445
1446void og_cmd_free(const struct og_cmd *cmd)
1447{
1448        struct og_msg_params *params = (struct og_msg_params *)&cmd->params;
1449        int i;
1450
1451        for (i = 0; i < params->ips_array_len; i++) {
1452                free((void *)params->ips_array[i]);
1453                free((void *)params->mac_array[i]);
1454        }
1455        free((void *)params->wol_type);
1456
1457        if (cmd->json)
1458                json_decref(cmd->json);
1459
1460        free((void *)cmd->ip);
1461        free((void *)cmd->mac);
1462        free((void *)cmd);
1463}
1464
1465static void og_cmd_init(struct og_cmd *cmd, enum og_rest_method method,
1466                        enum og_cmd_type type, json_t *root)
1467{
1468        cmd->type = type;
1469        cmd->method = method;
1470        cmd->params.ips_array[0] = strdup(cmd->ip);
1471        cmd->params.ips_array_len = 1;
1472        cmd->json = root;
1473}
1474
1475static int og_cmd_legacy_wol(const char *input, struct og_cmd *cmd)
1476{
1477        char wol_type[2] = {};
1478
1479        if (sscanf(input, "mar=%s", wol_type) != 1) {
1480                syslog(LOG_ERR, "malformed database legacy input\n");
1481                return -1;
1482        }
1483
1484        og_cmd_init(cmd, OG_METHOD_NO_HTTP, OG_CMD_WOL, NULL);
1485        cmd->params.mac_array[0] = strdup(cmd->mac);
1486        cmd->params.wol_type = strdup(wol_type);
1487
1488        return 0;
1489}
1490
1491static int og_cmd_legacy_shell_run(const char *input, struct og_cmd *cmd)
1492{
1493        json_t *root, *script, *echo;
1494
1495        script = json_string(input + 4);
1496        echo = json_boolean(false);
1497
1498        root = json_object();
1499        if (!root)
1500                return -1;
1501        json_object_set_new(root, "run", script);
1502        json_object_set_new(root, "echo", echo);
1503
1504        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SHELL_RUN, root);
1505
1506        return 0;
1507}
1508
1509static int og_cmd_legacy_session(const char *input, struct og_cmd *cmd)
1510{
1511        char part_str[OG_DB_SMALLINT_MAXLEN + 1];
1512        char disk_str[OG_DB_SMALLINT_MAXLEN + 1];
1513        json_t *root, *disk, *partition;
1514
1515        if (sscanf(input, "dsk=%s\rpar=%s\r", disk_str, part_str) != 2)
1516                return -1;
1517        partition = json_string(part_str);
1518        disk = json_string(disk_str);
1519
1520        root = json_object();
1521        if (!root)
1522                return -1;
1523        json_object_set_new(root, "partition", partition);
1524        json_object_set_new(root, "disk", disk);
1525
1526        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SESSION, root);
1527
1528        return 0;
1529}
1530
1531static int og_cmd_legacy_poweroff(const char *input, struct og_cmd *cmd)
1532{
1533        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_POWEROFF, NULL);
1534
1535        return 0;
1536}
1537
1538static int og_cmd_legacy_refresh(const char *input, struct og_cmd *cmd)
1539{
1540        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_REFRESH, NULL);
1541
1542        return 0;
1543}
1544
1545static int og_cmd_legacy_reboot(const char *input, struct og_cmd *cmd)
1546{
1547        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_REBOOT, NULL);
1548
1549        return 0;
1550}
1551
1552static int og_cmd_legacy_stop(const char *input, struct og_cmd *cmd)
1553{
1554        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_STOP, NULL);
1555
1556        return 0;
1557}
1558
1559static int og_cmd_legacy_hardware(const char *input, struct og_cmd *cmd)
1560{
1561        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_HARDWARE, NULL);
1562
1563        return 0;
1564}
1565
1566static int og_cmd_legacy_software(const char *input, struct og_cmd *cmd)
1567{
1568        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_SOFTWARE, NULL);
1569
1570        return 0;
1571}
1572
1573static int og_cmd_legacy_image_create(const char *input, struct og_cmd *cmd)
1574{
1575        json_t *root, *disk, *partition, *code, *image_id, *name, *repo;
1576        struct og_image_legacy img = {};
1577
1578        if (sscanf(input, "dsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s\r",
1579                   img.disk, img.part, img.code, img.image_id, img.name,
1580                   img.repo) != 6)
1581                return -1;
1582        image_id = json_string(img.image_id);
1583        partition = json_string(img.part);
1584        code = json_string(img.code);
1585        name = json_string(img.name);
1586        repo = json_string(img.repo);
1587        disk = json_string(img.disk);
1588
1589        root = json_object();
1590        if (!root)
1591                return -1;
1592        json_object_set_new(root, "partition", partition);
1593        json_object_set_new(root, "repository", repo);
1594        json_object_set_new(root, "id", image_id);
1595        json_object_set_new(root, "code", code);
1596        json_object_set_new(root, "name", name);
1597        json_object_set_new(root, "disk", disk);
1598
1599        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_CREATE, root);
1600
1601        return 0;
1602}
1603
1604#define OG_DB_RESTORE_TYPE_MAXLEN       64
1605
1606static int og_cmd_legacy_image_restore(const char *input, struct og_cmd *cmd)
1607{
1608        json_t *root, *disk, *partition, *image_id, *name, *repo;
1609        char restore_type_str[OG_DB_RESTORE_TYPE_MAXLEN + 1] = {};
1610        char software_id_str[OG_DB_INT_MAXLEN + 1] = {};
1611        json_t *software_id, *restore_type;
1612        struct og_image_legacy img = {};
1613
1614        if (sscanf(input,
1615                   "dsk=%s\rpar=%s\ridi=%s\rnci=%s\ripr=%s\rifs=%s\rptc=%s\r",
1616                   img.disk, img.part, img.image_id, img.name, img.repo,
1617                   software_id_str, restore_type_str) != 7)
1618                return -1;
1619
1620        restore_type = json_string(restore_type_str);
1621        software_id = json_string(software_id_str);
1622        image_id = json_string(img.image_id);
1623        partition = json_string(img.part);
1624        name = json_string(img.name);
1625        repo = json_string(img.repo);
1626        disk = json_string(img.disk);
1627
1628        root = json_object();
1629        if (!root)
1630                return -1;
1631        json_object_set_new(root, "profile", software_id);
1632        json_object_set_new(root, "partition", partition);
1633        json_object_set_new(root, "type", restore_type);
1634        json_object_set_new(root, "repository", repo);
1635        json_object_set_new(root, "id", image_id);
1636        json_object_set_new(root, "name", name);
1637        json_object_set_new(root, "disk", disk);
1638
1639        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, root);
1640
1641        return 0;
1642}
1643
1644static int og_cmd_legacy_setup(const char *input, struct og_cmd *cmd)
1645{
1646        json_t *root, *disk, *cache, *cache_size, *partition_setup, *object;
1647        struct og_legacy_partition part_cfg[OG_PARTITION_MAX] = {};
1648        char cache_size_str [OG_DB_INT_MAXLEN + 1];
1649        char disk_str [OG_DB_SMALLINT_MAXLEN + 1];
1650        json_t *part, *code, *fs, *size, *format;
1651        unsigned int partition_len = 0;
1652        const char *in_ptr;
1653        char cache_str[2];
1654
1655        if (sscanf(input, "dsk=%s\rcfg=dis=%*[^*]*che=%[^*]*tch=%[^!]!",
1656                   disk_str, cache_str, cache_size_str) != 3)
1657                return -1;
1658
1659        in_ptr = strstr(input, "!") + 1;
1660        while (strlen(in_ptr) > 0) {
1661                if(sscanf(in_ptr,
1662                          "par=%[^*]*cpt=%[^*]*sfi=%[^*]*tam=%[^*]*ope=%[^%%]%%",
1663                          part_cfg[partition_len].partition,
1664                          part_cfg[partition_len].code,
1665                          part_cfg[partition_len].filesystem,
1666                          part_cfg[partition_len].size,
1667                          part_cfg[partition_len].format) != 5)
1668                        return -1;
1669                in_ptr = strstr(in_ptr, "%") + 1;
1670                partition_len++;
1671        }
1672
1673        root = json_object();
1674        if (!root)
1675                return -1;
1676
1677        cache_size = json_string(cache_size_str);
1678        cache = json_string(cache_str);
1679        partition_setup = json_array();
1680        disk = json_string(disk_str);
1681
1682        for (unsigned int i = 0; i < partition_len; ++i) {
1683                object = json_object();
1684                if (!object) {
1685                        json_decref(root);
1686                        return -1;
1687                }
1688
1689                part = json_string(part_cfg[i].partition);
1690                fs = json_string(part_cfg[i].filesystem);
1691                format = json_string(part_cfg[i].format);
1692                code = json_string(part_cfg[i].code);
1693                size = json_string(part_cfg[i].size);
1694
1695                json_object_set_new(object, "partition", part);
1696                json_object_set_new(object, "filesystem", fs);
1697                json_object_set_new(object, "format", format);
1698                json_object_set_new(object, "code", code);
1699                json_object_set_new(object, "size", size);
1700
1701                json_array_append_new(partition_setup, object);
1702        }
1703
1704        json_object_set_new(root, "partition_setup", partition_setup);
1705        json_object_set_new(root, "cache_size", cache_size);
1706        json_object_set_new(root, "cache", cache);
1707        json_object_set_new(root, "disk", disk);
1708
1709        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SETUP, root);
1710
1711        return 0;
1712}
1713
1714static int og_cmd_legacy_run_schedule(const char *input, struct og_cmd *cmd)
1715{
1716        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, NULL);
1717
1718        return 0;
1719}
1720
1721static int og_cmd_legacy(const char *input, struct og_cmd *cmd)
1722{
1723        char legacy_cmd[32] = {};
1724        int err = -1;
1725
1726        if (sscanf(input, "nfn=%31s\r", legacy_cmd) != 1) {
1727                syslog(LOG_ERR, "malformed database legacy input\n");
1728                return -1;
1729        }
1730        input = strchr(input, '\r') + 1;
1731
1732        if (!strcmp(legacy_cmd, "Arrancar")) {
1733                err = og_cmd_legacy_wol(input, cmd);
1734        } else if (!strcmp(legacy_cmd, "EjecutarScript")) {
1735                err = og_cmd_legacy_shell_run(input, cmd);
1736        } else if (!strcmp(legacy_cmd, "IniciarSesion")) {
1737                err = og_cmd_legacy_session(input, cmd);
1738        } else if (!strcmp(legacy_cmd, "Apagar")) {
1739                err = og_cmd_legacy_poweroff(input, cmd);
1740        } else if (!strcmp(legacy_cmd, "Actualizar")) {
1741                err = og_cmd_legacy_refresh(input, cmd);
1742        } else if (!strcmp(legacy_cmd, "Reiniciar")) {
1743                err = og_cmd_legacy_reboot(input, cmd);
1744        } else if (!strcmp(legacy_cmd, "Purgar")) {
1745                err = og_cmd_legacy_stop(input, cmd);
1746        } else if (!strcmp(legacy_cmd, "InventarioHardware")) {
1747                err = og_cmd_legacy_hardware(input, cmd);
1748        } else if (!strcmp(legacy_cmd, "InventarioSoftware")) {
1749                err = og_cmd_legacy_software(input, cmd);
1750        } else if (!strcmp(legacy_cmd, "CrearImagen")) {
1751                err = og_cmd_legacy_image_create(input, cmd);
1752        } else if (!strcmp(legacy_cmd, "RestaurarImagen")) {
1753                err = og_cmd_legacy_image_restore(input, cmd);
1754        } else if (!strcmp(legacy_cmd, "Configurar")) {
1755                err = og_cmd_legacy_setup(input, cmd);
1756        } else if (!strcmp(legacy_cmd, "EjecutaComandosPendientes") ||
1757                   !strcmp(legacy_cmd, "Actualizar")) {
1758                err = og_cmd_legacy_run_schedule(input, cmd);
1759        }
1760
1761        return err;
1762}
1763
1764static int og_dbi_add_action(const struct og_dbi *dbi, const struct og_task *task,
1765                             struct og_cmd *cmd)
1766{
1767        char start_date_string[24];
1768        struct tm *start_date;
1769        const char *msglog;
1770        dbi_result result;
1771        time_t now;
1772
1773        time(&now);
1774        start_date = localtime(&now);
1775
1776        sprintf(start_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu",
1777                start_date->tm_year + 1900, start_date->tm_mon + 1,
1778                start_date->tm_mday, start_date->tm_hour, start_date->tm_min,
1779                start_date->tm_sec);
1780        result = dbi_conn_queryf(dbi->conn,
1781                                "INSERT INTO acciones (idordenador, "
1782                                "tipoaccion, idtipoaccion, descriaccion, ip, "
1783                                "sesion, idcomando, parametros, fechahorareg, "
1784                                "estado, resultado, ambito, idambito, "
1785                                "restrambito, idprocedimiento, idcentro, "
1786                                "idprogramacion) "
1787                                "VALUES (%d, %d, %d, '%s', '%s', %d, %d, '%s', "
1788                                "'%s', %d, %d, %d, %d, '%s', %d, %d, %d)",
1789                                cmd->client_id, EJECUCION_TAREA, task->task_id,
1790                                "", cmd->ip, 0, task->command_id,
1791                                task->params, start_date_string,
1792                                ACCION_INICIADA, ACCION_SINRESULTADO,
1793                                task->type_scope, task->scope, "",
1794                                task->procedure_id, task->center_id,
1795                                task->schedule_id);
1796        if (!result) {
1797                dbi_conn_error(dbi->conn, &msglog);
1798                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1799                       __func__, __LINE__, msglog);
1800                return -1;
1801        }
1802        cmd->id = dbi_conn_sequence_last(dbi->conn, NULL);
1803        dbi_result_free(result);
1804
1805        return 0;
1806}
1807
1808static int og_queue_task_command(struct og_dbi *dbi, const struct og_task *task,
1809                                 char *query)
1810{
1811        struct og_cmd *cmd;
1812        const char *msglog;
1813        dbi_result result;
1814
1815        result = dbi_conn_queryf(dbi->conn, query);
1816        if (!result) {
1817                dbi_conn_error(dbi->conn, &msglog);
1818                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1819                       __func__, __LINE__, msglog);
1820                return -1;
1821        }
1822
1823        while (dbi_result_next_row(result)) {
1824                cmd = (struct og_cmd *)calloc(1, sizeof(struct og_cmd));
1825                if (!cmd) {
1826                        dbi_result_free(result);
1827                        return -1;
1828                }
1829
1830                cmd->client_id  = dbi_result_get_uint(result, "idordenador");
1831                cmd->ip         = strdup(dbi_result_get_string(result, "ip"));
1832                cmd->mac        = strdup(dbi_result_get_string(result, "mac"));
1833
1834                og_cmd_legacy(task->params, cmd);
1835
1836                if (task->procedure_id) {
1837                        if (og_dbi_add_action(dbi, task, cmd)) {
1838                                dbi_result_free(result);
1839                                return -1;
1840                        }
1841                } else {
1842                        cmd->id = task->task_id;
1843                }
1844
1845                list_add_tail(&cmd->list, &cmd_list);
1846        }
1847
1848        dbi_result_free(result);
1849
1850        return 0;
1851}
1852
1853static int og_queue_task_group_clients(struct og_dbi *dbi, struct og_task *task,
1854                                       char *query)
1855{
1856
1857        const char *msglog;
1858        dbi_result result;
1859
1860        result = dbi_conn_queryf(dbi->conn, query);
1861        if (!result) {
1862                dbi_conn_error(dbi->conn, &msglog);
1863                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1864                       __func__, __LINE__, msglog);
1865                return -1;
1866        }
1867
1868        while (dbi_result_next_row(result)) {
1869                uint32_t group_id = dbi_result_get_uint(result, "idgrupo");
1870
1871                sprintf(query, "SELECT idgrupo FROM gruposordenadores "
1872                                "WHERE grupoid=%d", group_id);
1873                if (og_queue_task_group_clients(dbi, task, query)) {
1874                        dbi_result_free(result);
1875                        return -1;
1876                }
1877
1878                sprintf(query,"SELECT ip, mac, idordenador FROM ordenadores "
1879                              "WHERE grupoid=%d", group_id);
1880                if (og_queue_task_command(dbi, task, query)) {
1881                        dbi_result_free(result);
1882                        return -1;
1883                }
1884
1885        }
1886
1887        dbi_result_free(result);
1888
1889        return 0;
1890}
1891
1892static int og_queue_task_group_classrooms(struct og_dbi *dbi,
1893                                          struct og_task *task, char *query)
1894{
1895
1896        const char *msglog;
1897        dbi_result result;
1898
1899        result = dbi_conn_queryf(dbi->conn, query);
1900        if (!result) {
1901                dbi_conn_error(dbi->conn, &msglog);
1902                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1903                       __func__, __LINE__, msglog);
1904                return -1;
1905        }
1906
1907        while (dbi_result_next_row(result)) {
1908                uint32_t group_id = dbi_result_get_uint(result, "idgrupo");
1909
1910                sprintf(query, "SELECT idgrupo FROM grupos "
1911                                "WHERE grupoid=%d AND tipo=%d", group_id, AMBITO_GRUPOSAULAS);
1912                if (og_queue_task_group_classrooms(dbi, task, query)) {
1913                        dbi_result_free(result);
1914                        return -1;
1915                }
1916
1917                sprintf(query,
1918                        "SELECT ip,mac,idordenador "
1919                        "FROM ordenadores INNER JOIN aulas "
1920                        "WHERE ordenadores.idaula=aulas.idaula "
1921                        "AND aulas.grupoid=%d",
1922                        group_id);
1923                if (og_queue_task_command(dbi, task, query)) {
1924                        dbi_result_free(result);
1925                        return -1;
1926                }
1927
1928        }
1929
1930        dbi_result_free(result);
1931
1932        return 0;
1933}
1934
1935static int og_queue_task_clients(struct og_dbi *dbi, struct og_task *task)
1936{
1937        char query[4096];
1938
1939        switch (task->type_scope) {
1940                case AMBITO_CENTROS:
1941                        sprintf(query,
1942                                "SELECT ip,mac,idordenador "
1943                                "FROM ordenadores INNER JOIN aulas "
1944                                "WHERE ordenadores.idaula=aulas.idaula "
1945                                "AND idcentro=%d",
1946                                task->scope);
1947                        return og_queue_task_command(dbi, task, query);
1948                case AMBITO_GRUPOSAULAS:
1949                        sprintf(query,
1950                                "SELECT idgrupo FROM grupos "
1951                                "WHERE idgrupo=%i AND tipo=%d",
1952                                task->scope, AMBITO_GRUPOSAULAS);
1953                        return og_queue_task_group_classrooms(dbi, task, query);
1954                case AMBITO_AULAS:
1955                        sprintf(query,
1956                                "SELECT ip,mac,idordenador FROM ordenadores "
1957                                "WHERE idaula=%d",
1958                                task->scope);
1959                        return og_queue_task_command(dbi, task, query);
1960                case AMBITO_GRUPOSORDENADORES:
1961                        sprintf(query,
1962                                "SELECT idgrupo FROM gruposordenadores "
1963                                "WHERE idgrupo = %d",
1964                                task->scope);
1965                        return og_queue_task_group_clients(dbi, task, query);
1966                case AMBITO_ORDENADORES:
1967                        sprintf(query,
1968                                "SELECT ip, mac, idordenador FROM ordenadores "
1969                                "WHERE idordenador = %d",
1970                                task->scope);
1971                        return og_queue_task_command(dbi, task, query);
1972        }
1973        return 0;
1974}
1975
1976int og_dbi_queue_procedure(struct og_dbi *dbi, struct og_task *task)
1977{
1978        uint32_t procedure_id;
1979        const char *msglog;
1980        dbi_result result;
1981
1982        result = dbi_conn_queryf(dbi->conn,
1983                        "SELECT parametros, procedimientoid, idcomando "
1984                        "FROM procedimientos_acciones "
1985                        "WHERE idprocedimiento=%d ORDER BY orden", task->procedure_id);
1986        if (!result) {
1987                dbi_conn_error(dbi->conn, &msglog);
1988                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1989                       __func__, __LINE__, msglog);
1990                return -1;
1991        }
1992
1993        while (dbi_result_next_row(result)) {
1994                procedure_id = dbi_result_get_uint(result, "procedimientoid");
1995                if (procedure_id > 0) {
1996                        task->procedure_id = procedure_id;
1997                        if (og_dbi_queue_procedure(dbi, task))
1998                                return -1;
1999                        continue;
2000                }
2001
2002                task->params    = strdup(dbi_result_get_string(result, "parametros"));
2003                task->command_id = dbi_result_get_uint(result, "idcomando");
2004                if (og_queue_task_clients(dbi, task))
2005                        return -1;
2006        }
2007
2008        dbi_result_free(result);
2009
2010        return 0;
2011}
2012
2013static int og_dbi_queue_task(struct og_dbi *dbi, uint32_t task_id,
2014                             uint32_t schedule_id)
2015{
2016        struct og_task task = {};
2017        uint32_t task_id_next;
2018        const char *msglog;
2019        dbi_result result;
2020
2021        task.schedule_id = schedule_id;
2022
2023        result = dbi_conn_queryf(dbi->conn,
2024                        "SELECT tareas_acciones.orden, "
2025                                "tareas_acciones.idprocedimiento, "
2026                                "tareas_acciones.tareaid, "
2027                                "tareas.idtarea, "
2028                                "tareas.idcentro, "
2029                                "tareas.ambito, "
2030                                "tareas.idambito, "
2031                                "tareas.restrambito "
2032                        " FROM tareas"
2033                                " INNER JOIN tareas_acciones ON tareas_acciones.idtarea=tareas.idtarea"
2034                        " WHERE tareas_acciones.idtarea=%u ORDER BY tareas_acciones.orden ASC", task_id);
2035        if (!result) {
2036                dbi_conn_error(dbi->conn, &msglog);
2037                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2038                       __func__, __LINE__, msglog);
2039                return -1;
2040        }
2041
2042        while (dbi_result_next_row(result)) {
2043                task_id_next = dbi_result_get_uint(result, "tareaid");
2044
2045                if (task_id_next > 0) {
2046                        if (og_dbi_queue_task(dbi, task_id_next, schedule_id))
2047                                return -1;
2048
2049                        continue;
2050                }
2051                task.task_id = dbi_result_get_uint(result, "idtarea");
2052                task.center_id = dbi_result_get_uint(result, "idcentro");
2053                task.procedure_id = dbi_result_get_uint(result, "idprocedimiento");
2054                task.type_scope = dbi_result_get_uint(result, "ambito");
2055                task.scope = dbi_result_get_uint(result, "idambito");
2056                task.filtered_scope = dbi_result_get_string(result, "restrambito");
2057
2058                og_dbi_queue_procedure(dbi, &task);
2059        }
2060
2061        dbi_result_free(result);
2062
2063        return 0;
2064}
2065
2066static int og_dbi_queue_command(struct og_dbi *dbi, uint32_t task_id,
2067                                uint32_t schedule_id)
2068{
2069        struct og_task task = {};
2070        const char *msglog;
2071        dbi_result result;
2072        char query[4096];
2073
2074        result = dbi_conn_queryf(dbi->conn,
2075                        "SELECT idaccion, idcentro, idordenador, parametros "
2076                        "FROM acciones "
2077                        "WHERE sesion = %u", task_id);
2078        if (!result) {
2079                dbi_conn_error(dbi->conn, &msglog);
2080                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2081                       __func__, __LINE__, msglog);
2082                return -1;
2083        }
2084
2085        while (dbi_result_next_row(result)) {
2086                task.task_id = dbi_result_get_uint(result, "idaccion");
2087                task.center_id = dbi_result_get_uint(result, "idcentro");
2088                task.scope = dbi_result_get_uint(result, "idordenador");
2089                task.params = strdup(dbi_result_get_string(result, "parametros"));
2090
2091                sprintf(query,
2092                        "SELECT ip, mac, idordenador FROM ordenadores "
2093                        "WHERE idordenador = %d",
2094                        task.scope);
2095                if (og_queue_task_command(dbi, &task, query)) {
2096                        dbi_result_free(result);
2097                        return -1;
2098                }
2099        }
2100
2101        dbi_result_free(result);
2102
2103        return 0;
2104}
2105
2106int og_dbi_update_action(uint32_t id, bool success)
2107{
2108        char end_date_string[24];
2109        struct tm *end_date;
2110        const char *msglog;
2111        struct og_dbi *dbi;
2112        uint8_t status = 2;
2113        dbi_result result;
2114        time_t now;
2115
2116        if (!id)
2117                return 0;
2118
2119        dbi = og_dbi_open(&dbi_config);
2120        if (!dbi) {
2121                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2122                       __func__, __LINE__);
2123                return -1;
2124        }
2125
2126        time(&now);
2127        end_date = localtime(&now);
2128
2129        sprintf(end_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu",
2130                end_date->tm_year + 1900, end_date->tm_mon + 1,
2131                end_date->tm_mday, end_date->tm_hour, end_date->tm_min,
2132                end_date->tm_sec);
2133        result = dbi_conn_queryf(dbi->conn,
2134                                 "UPDATE acciones SET fechahorafin='%s', "
2135                                 "estado=%d, resultado=%d WHERE idaccion=%d",
2136                                 end_date_string, ACCION_FINALIZADA,
2137                                 status - success, id);
2138
2139        if (!result) {
2140                dbi_conn_error(dbi->conn, &msglog);
2141                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2142                       __func__, __LINE__, msglog);
2143                og_dbi_close(dbi);
2144                return -1;
2145        }
2146        dbi_result_free(result);
2147        og_dbi_close(dbi);
2148
2149        return 0;
2150}
2151
2152void og_schedule_run(unsigned int task_id, unsigned int schedule_id,
2153                     enum og_schedule_type type)
2154{
2155        struct og_msg_params params = {};
2156        bool duplicated = false;
2157        struct og_cmd *cmd, *next;
2158        struct og_dbi *dbi;
2159        unsigned int i;
2160
2161        dbi = og_dbi_open(&dbi_config);
2162        if (!dbi) {
2163                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2164                       __func__, __LINE__);
2165                return;
2166        }
2167
2168        switch (type) {
2169        case OG_SCHEDULE_TASK:
2170                og_dbi_queue_task(dbi, task_id, schedule_id);
2171                break;
2172        case OG_SCHEDULE_PROCEDURE:
2173        case OG_SCHEDULE_COMMAND:
2174                og_dbi_queue_command(dbi, task_id, schedule_id);
2175                break;
2176        }
2177        og_dbi_close(dbi);
2178
2179        list_for_each_entry(cmd, &cmd_list, list) {
2180                for (i = 0; i < params.ips_array_len; i++) {
2181                        if (!strncmp(cmd->ip, params.ips_array[i],
2182                                     OG_DB_IP_MAXLEN)) {
2183                                duplicated = true;
2184                                break;
2185                        }
2186                }
2187
2188                if (!duplicated)
2189                        params.ips_array[params.ips_array_len++] = cmd->ip;
2190                else
2191                        duplicated = false;
2192        }
2193
2194        list_for_each_entry_safe(cmd, next, &cmd_list, list) {
2195                if (cmd->type != OG_CMD_WOL)
2196                        continue;
2197
2198                if (Levanta((char **)cmd->params.ips_array,
2199                            (char **)cmd->params.mac_array,
2200                            cmd->params.ips_array_len,
2201                            (char *)cmd->params.wol_type))
2202                        og_dbi_update_action(cmd->id, true);
2203
2204                list_del(&cmd->list);
2205                og_cmd_free(cmd);
2206        }
2207
2208        og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, &params, NULL);
2209}
2210
2211static int og_cmd_task_post(json_t *element, struct og_msg_params *params)
2212{
2213        struct og_cmd *cmd;
2214        struct og_dbi *dbi;
2215        const char *key;
2216        json_t *value;
2217        int err;
2218
2219        if (json_typeof(element) != JSON_OBJECT)
2220                return -1;
2221
2222        json_object_foreach(element, key, value) {
2223                if (!strcmp(key, "task")) {
2224                        err = og_json_parse_string(value, &params->task_id);
2225                        params->flags |= OG_REST_PARAM_TASK;
2226                }
2227
2228                if (err < 0)
2229                        break;
2230        }
2231
2232        if (!og_msg_params_validate(params, OG_REST_PARAM_TASK))
2233                return -1;
2234
2235        dbi = og_dbi_open(&dbi_config);
2236        if (!dbi) {
2237                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2238                           __func__, __LINE__);
2239                return -1;
2240        }
2241
2242        og_schedule_run(atoi(params->task_id), 0, OG_SCHEDULE_TASK);
2243        og_dbi_close(dbi);
2244
2245        list_for_each_entry(cmd, &cmd_list, list)
2246                params->ips_array[params->ips_array_len++] = cmd->ip;
2247
2248        return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params,
2249                               NULL);
2250}
2251
[c46fa3c]2252static int og_dbi_scope_get_center(struct og_dbi *dbi, json_t *array)
2253{
[3d253e6]2254        char center_name[OG_DB_CENTER_NAME_MAXLEN + 1] = {};
2255        const char *msglog;
2256        uint32_t center_id;
2257        dbi_result result;
2258        json_t *center;
2259
2260        result = dbi_conn_queryf(dbi->conn,
2261                                 "SELECT nombrecentro, idcentro FROM centros");
2262        if (!result) {
2263                dbi_conn_error(dbi->conn, &msglog);
2264                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2265                       __func__, __LINE__, msglog);
2266                return -1;
2267        }
2268
2269        while (dbi_result_next_row(result)) {
2270                center_id = dbi_result_get_uint(result, "idcentro");
2271                strncpy(center_name,
2272                        dbi_result_get_string(result, "nombrecentro"),
2273                        OG_DB_CENTER_NAME_MAXLEN);
2274
2275                center = json_object();
2276                if (!center) {
2277                        dbi_result_free(result);
2278                        return -1;
2279                }
2280
2281                json_object_set_new(center, "name", json_string(center_name));
2282                json_object_set_new(center, "type", json_string("center"));
2283                json_object_set_new(center, "id", json_integer(center_id));
2284                json_object_set_new(center, "scope", json_array());
2285                json_array_append(array, center);
2286                json_decref(center);
2287        }
2288        dbi_result_free(result);
2289
2290        return 0;
2291}
2292
[c46fa3c]2293static int og_dbi_scope_get_room(struct og_dbi *dbi, json_t *array,
2294                                 uint32_t center_id)
2295{
[3d253e6]2296        char room_name[OG_DB_ROOM_NAME_MAXLEN + 1] = {};
2297        const char *msglog;
2298        dbi_result result;
2299        uint32_t room_id;
2300        json_t *room;
2301
2302        result = dbi_conn_queryf(dbi->conn,
2303                                 "SELECT idaula, nombreaula FROM aulas WHERE "
2304                                 "idcentro=%d",
2305                                 center_id);
2306        if (!result) {
2307                dbi_conn_error(dbi->conn, &msglog);
2308                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2309                       __func__, __LINE__, msglog);
2310                return -1;
2311        }
2312
2313        while (dbi_result_next_row(result)) {
2314                room_id = dbi_result_get_uint(result, "idaula");
2315                strncpy(room_name,
2316                        dbi_result_get_string(result, "nombreaula"),
2317                        OG_DB_CENTER_NAME_MAXLEN);
2318
2319                room = json_object();
2320                if (!room) {
2321                        dbi_result_free(result);
2322                        return -1;
2323                }
2324
2325                json_object_set_new(room, "name", json_string(room_name));
2326                json_object_set_new(room, "type", json_string("room"));
2327                json_object_set_new(room, "id", json_integer(room_id));
2328                json_object_set_new(room, "scope", json_array());
2329                json_array_append(array, room);
2330                json_decref(room);
2331        }
2332        dbi_result_free(result);
2333
2334        return 0;
2335}
2336
[c46fa3c]2337static int og_dbi_scope_get_computer(struct og_dbi *dbi, json_t *array,
2338                                     uint32_t room_id)
2339{
[3d253e6]2340        char computer_name[OG_DB_COMPUTER_NAME_MAXLEN + 1] = {};
2341        uint32_t computer_id;
2342        const char *msglog;
2343        dbi_result result;
2344        json_t *computer;
2345
2346        result = dbi_conn_queryf(dbi->conn,
2347                                 "SELECT idordenador, nombreordenador, ip "
2348                                 "FROM ordenadores WHERE idaula=%d",
2349                                 room_id);
2350        if (!result) {
2351                dbi_conn_error(dbi->conn, &msglog);
2352                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2353                       __func__, __LINE__, msglog);
2354                return -1;
2355        }
2356
2357        while (dbi_result_next_row(result)) {
2358                computer_id = dbi_result_get_uint(result, "idordenador");
2359                strncpy(computer_name,
2360                        dbi_result_get_string(result, "nombreordenador"),
2361                        OG_DB_CENTER_NAME_MAXLEN);
2362
2363                computer = json_object();
2364                if (!computer) {
2365                        dbi_result_free(result);
2366                        return -1;
2367                }
2368
2369                json_object_set_new(computer, "name", json_string(computer_name));
2370                json_object_set_new(computer, "type", json_string("computer"));
2371                json_object_set_new(computer, "id", json_integer(computer_id));
2372                json_object_set_new(computer, "scope", json_array());
2373                json_array_append(array, computer);
2374                json_decref(computer);
2375        }
2376        dbi_result_free(result);
2377
2378        return 0;
2379}
2380
2381static int og_cmd_scope_get(json_t *element, struct og_msg_params *params,
2382                            char *buffer_reply)
2383{
2384        json_t *root, *children_root, *children_center, *children_room,
2385               *center_value, *room_value;
2386        uint32_t center_id, room_id, index1, index2;
2387        struct og_dbi *dbi;
2388
2389        struct og_buffer og_buffer = {
2390                .data = buffer_reply
2391        };
2392
2393        root = json_object();
2394        children_root = json_array();
2395        if (!root || !children_root)
2396                return -1;
2397
2398        json_object_set(root, "scope", children_root);
2399
2400        dbi = og_dbi_open(&dbi_config);
2401        if (!dbi) {
2402                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2403                       __func__, __LINE__);
2404                return -1;
2405        }
2406
[c46fa3c]2407        if (og_dbi_scope_get_center(dbi, children_root)) {
[3d253e6]2408                og_dbi_close(dbi);
2409                return -1;
2410        }
2411
2412        json_array_foreach(children_root, index1, center_value) {
2413                center_id = json_integer_value(json_object_get(center_value,"id"));
2414                children_center = json_object_get(center_value, "scope");
[c46fa3c]2415                if (og_dbi_scope_get_room(dbi, children_center, center_id)) {
[3d253e6]2416                        og_dbi_close(dbi);
2417                        return -1;
2418                }
2419
2420                json_array_foreach(children_center, index2, room_value) {
2421                        room_id = json_integer_value(json_object_get(room_value, "id"));
2422                        children_room = json_object_get(room_value, "scope");
[c46fa3c]2423                        if (og_dbi_scope_get_computer(dbi, children_room, room_id)) {
[3d253e6]2424                                og_dbi_close(dbi);
2425                                return -1;
2426                        }
2427                }
2428        }
2429
2430        og_dbi_close(dbi);
2431
2432        json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
2433        json_decref(root);
2434
2435        return 0;
2436}
2437
[04ca20e]2438int og_dbi_schedule_get(void)
2439{
2440        uint32_t schedule_id, task_id;
2441        struct og_schedule_time time;
2442        struct og_dbi *dbi;
2443        const char *msglog;
2444        dbi_result result;
2445
2446        dbi = og_dbi_open(&dbi_config);
2447        if (!dbi) {
2448                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2449                       __func__, __LINE__);
2450                return -1;
2451        }
2452
2453        result = dbi_conn_queryf(dbi->conn,
2454                                 "SELECT idprogramacion, tipoaccion, identificador, "
2455                                 "sesion, annos, meses, diario, dias, semanas, horas, "
2456                                 "ampm, minutos FROM programaciones "
2457                                 "WHERE suspendida = 0");
2458        if (!result) {
2459                dbi_conn_error(dbi->conn, &msglog);
2460                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2461                       __func__, __LINE__, msglog);
2462                og_dbi_close(dbi);
2463                return -1;
2464        }
2465
2466        while (dbi_result_next_row(result)) {
2467                memset(&time, 0, sizeof(time));
2468                schedule_id = dbi_result_get_uint(result, "idprogramacion");
2469                task_id = dbi_result_get_uint(result, "identificador");
2470                time.years = dbi_result_get_uint(result, "annos");
2471                time.months = dbi_result_get_uint(result, "meses");
2472                time.weeks = dbi_result_get_uint(result, "semanas");
2473                time.week_days = dbi_result_get_uint(result, "dias");
2474                time.days = dbi_result_get_uint(result, "diario");
2475                time.hours = dbi_result_get_uint(result, "horas");
2476                time.am_pm = dbi_result_get_uint(result, "ampm");
2477                time.minutes = dbi_result_get_uint(result, "minutos");
2478                time.on_start = true;
2479
2480                og_schedule_create(schedule_id, task_id, OG_SCHEDULE_TASK,
2481                                   &time);
2482        }
2483
2484        dbi_result_free(result);
2485        og_dbi_close(dbi);
2486
2487        return 0;
2488}
2489
2490static int og_dbi_schedule_create(struct og_dbi *dbi,
2491                                  struct og_msg_params *params,
2492                                  uint32_t *schedule_id,
2493                                  enum og_schedule_type schedule_type)
2494{
2495        uint8_t suspended = 0;
2496        uint32_t session = 0;
2497        const char *msglog;
2498        dbi_result result;
2499        uint8_t type;
2500
2501        switch (schedule_type) {
2502        case OG_SCHEDULE_TASK:
2503                type = 3;
2504                break;
2505        case OG_SCHEDULE_PROCEDURE:
2506                type = 2;
2507                break;
2508        case OG_SCHEDULE_COMMAND:
2509                session = atoi(params->task_id);
2510                type = 1;
2511                break;
2512        }
2513
2514        result = dbi_conn_queryf(dbi->conn,
2515                                 "INSERT INTO programaciones (tipoaccion,"
2516                                 " identificador, nombrebloque, annos, meses,"
2517                                 " semanas, dias, diario, horas, ampm, minutos,"
2518                                 " suspendida, sesion) VALUES (%d, %s, '%s',"
2519                                 " %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
2520                                 type, params->task_id, params->name,
2521                                 params->time.years, params->time.months,
2522                                 params->time.weeks, params->time.week_days,
2523                                 params->time.days, params->time.hours,
2524                                 params->time.am_pm, params->time.minutes,
2525                                 suspended, session);
2526        if (!result) {
2527                dbi_conn_error(dbi->conn, &msglog);
2528                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2529                       __func__, __LINE__, msglog);
2530                return -1;
2531        }
2532        dbi_result_free(result);
2533
2534        *schedule_id = dbi_conn_sequence_last(dbi->conn, NULL);
2535
2536        return 0;
2537}
2538
2539static int og_dbi_schedule_update(struct og_dbi *dbi,
2540                                  struct og_msg_params *params)
2541{
2542        const char *msglog;
2543        dbi_result result;
2544        uint8_t type = 3;
2545
2546        result = dbi_conn_queryf(dbi->conn,
2547                                 "UPDATE programaciones SET tipoaccion=%d, "
2548                                 "identificador='%s', nombrebloque='%s', "
2549                                 "annos=%d, meses=%d, "
2550                                 "diario=%d, horas=%d, ampm=%d, minutos=%d "
2551                                 "WHERE idprogramacion='%s'",
2552                                 type, params->task_id, params->name,
2553                                 params->time.years, params->time.months,
2554                                 params->time.days, params->time.hours,
2555                                 params->time.am_pm, params->time.minutes,
2556                                 params->id);
2557
2558        if (!result) {
2559                dbi_conn_error(dbi->conn, &msglog);
2560                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2561                       __func__, __LINE__, msglog);
2562                return -1;
2563        }
2564        dbi_result_free(result);
2565
2566        return 0;
2567}
2568
2569static int og_dbi_schedule_delete(struct og_dbi *dbi, uint32_t id)
2570{
2571        const char *msglog;
2572        dbi_result result;
2573
2574        result = dbi_conn_queryf(dbi->conn,
2575                                 "DELETE FROM programaciones WHERE idprogramacion=%d",
2576                                 id);
2577        if (!result) {
2578                dbi_conn_error(dbi->conn, &msglog);
2579                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2580                       __func__, __LINE__, msglog);
2581                return -1;
2582        }
2583        dbi_result_free(result);
2584
2585        return 0;
2586}
2587
2588struct og_db_schedule {
2589        uint32_t                id;
2590        uint32_t                task_id;
2591        const char              *name;
2592        struct og_schedule_time time;
2593        uint32_t                week_days;
2594        uint32_t                weeks;
2595        uint32_t                suspended;
2596        uint32_t                session;
2597};
2598
2599static int og_dbi_schedule_get_json(struct og_dbi *dbi, json_t *root,
2600                                    const char *task_id, const char *schedule_id)
2601{
2602        struct og_db_schedule schedule;
2603        json_t *obj, *array;
2604        const char *msglog;
2605        dbi_result result;
2606        int err = 0;
2607
2608        if (task_id) {
2609                result = dbi_conn_queryf(dbi->conn,
2610                                         "SELECT idprogramacion,"
2611                                         "       identificador, nombrebloque,"
2612                                         "       annos, meses, diario, dias,"
2613                                         "       semanas, horas, ampm,"
2614                                         "       minutos,suspendida, sesion "
2615                                         "FROM programaciones "
2616                                         "WHERE identificador=%d",
2617                                         atoi(task_id));
2618        } else if (schedule_id) {
2619                result = dbi_conn_queryf(dbi->conn,
2620                                         "SELECT idprogramacion,"
2621                                         "       identificador, nombrebloque,"
2622                                         "       annos, meses, diario, dias,"
2623                                         "       semanas, horas, ampm,"
2624                                         "       minutos,suspendida, sesion "
2625                                         "FROM programaciones "
2626                                         "WHERE idprogramacion=%d",
2627                                         atoi(schedule_id));
2628        } else {
2629                result = dbi_conn_queryf(dbi->conn,
2630                                         "SELECT idprogramacion,"
2631                                         "       identificador, nombrebloque,"
2632                                         "       annos, meses, diario, dias,"
2633                                         "       semanas, horas, ampm,"
2634                                         "       minutos,suspendida, sesion "
2635                                         "FROM programaciones");
2636        }
2637
2638        if (!result) {
2639                dbi_conn_error(dbi->conn, &msglog);
2640                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2641                       __func__, __LINE__, msglog);
2642                return -1;
2643        }
2644
2645        array = json_array();
2646        if (!array)
2647                return -1;
2648
2649        while (dbi_result_next_row(result)) {
2650                schedule.id = dbi_result_get_uint(result, "idprogramacion");
2651                schedule.task_id = dbi_result_get_uint(result, "identificador");
2652                schedule.name = dbi_result_get_string(result, "nombrebloque");
2653                schedule.time.years = dbi_result_get_uint(result, "annos");
2654                schedule.time.months = dbi_result_get_uint(result, "meses");
2655                schedule.time.days = dbi_result_get_uint(result, "diario");
2656                schedule.time.hours = dbi_result_get_uint(result, "horas");
2657                schedule.time.am_pm = dbi_result_get_uint(result, "ampm");
2658                schedule.time.minutes = dbi_result_get_uint(result, "minutos");
2659                schedule.week_days = dbi_result_get_uint(result, "dias");
2660                schedule.weeks = dbi_result_get_uint(result, "semanas");
2661                schedule.suspended = dbi_result_get_uint(result, "suspendida");
2662                schedule.session = dbi_result_get_uint(result, "sesion");
2663
2664                obj = json_object();
2665                if (!obj) {
2666                        err = -1;
2667                        break;
2668                }
2669                json_object_set_new(obj, "id", json_integer(schedule.id));
2670                json_object_set_new(obj, "task", json_integer(schedule.task_id));
2671                json_object_set_new(obj, "name", json_string(schedule.name));
2672                json_object_set_new(obj, "years", json_integer(schedule.time.years));
2673                json_object_set_new(obj, "months", json_integer(schedule.time.months));
2674                json_object_set_new(obj, "days", json_integer(schedule.time.days));
2675                json_object_set_new(obj, "hours", json_integer(schedule.time.hours));
2676                json_object_set_new(obj, "am_pm", json_integer(schedule.time.am_pm));
2677                json_object_set_new(obj, "minutes", json_integer(schedule.time.minutes));
2678                json_object_set_new(obj, "week_days", json_integer(schedule.week_days));
2679                json_object_set_new(obj, "weeks", json_integer(schedule.weeks));
2680                json_object_set_new(obj, "suspended", json_integer(schedule.suspended));
2681                json_object_set_new(obj, "session", json_integer(schedule.session));
2682
2683                json_array_append_new(array, obj);
2684        }
2685
2686        json_object_set_new(root, "schedule", array);
2687
2688        dbi_result_free(result);
2689
2690        return err;
2691}
2692
2693static int og_task_schedule_create(struct og_msg_params *params)
2694{
2695        enum og_schedule_type type;
2696        uint32_t schedule_id;
2697        struct og_dbi *dbi;
2698        int err;
2699
2700        if (!strcmp(params->type, "task"))
2701                type = OG_SCHEDULE_TASK;
2702        else if (!strcmp(params->type, "procedure"))
2703                type = OG_SCHEDULE_PROCEDURE;
2704        else if (!strcmp(params->type, "command"))
2705                type = OG_SCHEDULE_COMMAND;
2706        else
2707                return -1;
2708
2709        dbi = og_dbi_open(&dbi_config);
2710        if (!dbi) {
2711                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2712                       __func__, __LINE__);
2713                return -1;
2714        }
2715
2716        err = og_dbi_schedule_create(dbi, params, &schedule_id, type);
2717        if (err < 0) {
2718                og_dbi_close(dbi);
2719                return -1;
2720        }
2721        og_schedule_create(schedule_id, atoi(params->task_id), type,
2722                           &params->time);
2723        og_schedule_refresh(og_loop);
2724        og_dbi_close(dbi);
2725
2726        return 0;
2727}
2728
2729static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params)
2730{
2731        const char *key;
2732        json_t *value;
2733        int err;
2734
2735        if (json_typeof(element) != JSON_OBJECT)
2736                return -1;
2737
2738        json_object_foreach(element, key, value) {
2739                if (!strcmp(key, "task")) {
2740                        err = og_json_parse_string(value, &params->task_id);
2741                        params->flags |= OG_REST_PARAM_TASK;
2742                } else if (!strcmp(key, "name")) {
2743                        err = og_json_parse_string(value, &params->name);
2744                        params->flags |= OG_REST_PARAM_NAME;
2745                } else if (!strcmp(key, "when")) {
2746                        err = og_json_parse_time_params(value, params);
2747                } else if (!strcmp(key, "type")) {
2748                        err = og_json_parse_string(value, &params->type);
2749                        params->flags |= OG_REST_PARAM_TYPE;
2750                }
2751
2752                if (err < 0)
2753                        break;
2754        }
2755
2756        if (!og_msg_params_validate(params, OG_REST_PARAM_TASK |
2757                                            OG_REST_PARAM_NAME |
2758                                            OG_REST_PARAM_TIME_YEARS |
2759                                            OG_REST_PARAM_TIME_MONTHS |
2760                                            OG_REST_PARAM_TIME_WEEKS |
2761                                            OG_REST_PARAM_TIME_WEEK_DAYS |
2762                                            OG_REST_PARAM_TIME_DAYS |
2763                                            OG_REST_PARAM_TIME_HOURS |
2764                                            OG_REST_PARAM_TIME_MINUTES |
2765                                            OG_REST_PARAM_TIME_AM_PM |
2766                                            OG_REST_PARAM_TYPE))
2767                return -1;
2768
2769        return og_task_schedule_create(params);
2770}
2771
2772static int og_cmd_schedule_update(json_t *element, struct og_msg_params *params)
2773{
2774        struct og_dbi *dbi;
2775        const char *key;
2776        json_t *value;
2777        int err;
2778
2779        if (json_typeof(element) != JSON_OBJECT)
2780                return -1;
2781
2782        json_object_foreach(element, key, value) {
2783                if (!strcmp(key, "id")) {
2784                        err = og_json_parse_string(value, &params->id);
2785                        params->flags |= OG_REST_PARAM_ID;
2786                } else if (!strcmp(key, "task")) {
2787                        err = og_json_parse_string(value, &params->task_id);
2788                        params->flags |= OG_REST_PARAM_TASK;
2789                } else if (!strcmp(key, "name")) {
2790                        err = og_json_parse_string(value, &params->name);
2791                        params->flags |= OG_REST_PARAM_NAME;
2792                } else if (!strcmp(key, "when"))
2793                        err = og_json_parse_time_params(value, params);
2794
2795                if (err < 0)
2796                        break;
2797        }
2798
2799        if (!og_msg_params_validate(params, OG_REST_PARAM_ID |
2800                                            OG_REST_PARAM_TASK |
2801                                            OG_REST_PARAM_NAME |
2802                                            OG_REST_PARAM_TIME_YEARS |
2803                                            OG_REST_PARAM_TIME_MONTHS |
2804                                            OG_REST_PARAM_TIME_DAYS |
2805                                            OG_REST_PARAM_TIME_HOURS |
2806                                            OG_REST_PARAM_TIME_MINUTES |
2807                                            OG_REST_PARAM_TIME_AM_PM))
2808                return -1;
2809
2810        dbi = og_dbi_open(&dbi_config);
2811        if (!dbi) {
2812                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2813                           __func__, __LINE__);
2814                return -1;
2815        }
2816
2817        err = og_dbi_schedule_update(dbi, params);
2818        og_dbi_close(dbi);
2819
2820        if (err < 0)
2821                return err;
2822
2823        og_schedule_update(og_loop, atoi(params->id), atoi(params->task_id),
2824                           &params->time);
2825        og_schedule_refresh(og_loop);
2826
2827        return err;
2828}
2829
2830static int og_cmd_schedule_delete(json_t *element, struct og_msg_params *params)
2831{
2832        struct og_dbi *dbi;
2833        const char *key;
2834        json_t *value;
2835        int err;
2836
2837        if (json_typeof(element) != JSON_OBJECT)
2838                return -1;
2839
2840        json_object_foreach(element, key, value) {
2841                if (!strcmp(key, "id")) {
2842                        err = og_json_parse_string(value, &params->id);
2843                        params->flags |= OG_REST_PARAM_ID;
2844                } else {
2845                        return -1;
2846                }
2847
2848                if (err < 0)
2849                        break;
2850        }
2851
2852        if (!og_msg_params_validate(params, OG_REST_PARAM_ID))
2853                return -1;
2854
2855        dbi = og_dbi_open(&dbi_config);
2856        if (!dbi) {
2857                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2858                           __func__, __LINE__);
2859                return -1;
2860        }
2861
2862        err = og_dbi_schedule_delete(dbi, atoi(params->id));
2863        og_dbi_close(dbi);
2864
2865        og_schedule_delete(og_loop, atoi(params->id));
2866
2867        return err;
2868}
2869
2870static int og_cmd_schedule_get(json_t *element, struct og_msg_params *params,
2871                               char *buffer_reply)
2872{
2873        struct og_buffer og_buffer = {
2874                .data   = buffer_reply,
2875        };
2876        json_t *schedule_root;
2877        struct og_dbi *dbi;
2878        const char *key;
2879        json_t *value;
2880        int err;
2881
2882        if (element) {
2883                if (json_typeof(element) != JSON_OBJECT)
2884                        return -1;
2885
2886                json_object_foreach(element, key, value) {
2887                        if (!strcmp(key, "task")) {
2888                                err = og_json_parse_string(value,
2889                                                           &params->task_id);
2890                        } else if (!strcmp(key, "id")) {
2891                                err = og_json_parse_string(value, &params->id);
2892                        } else {
2893                                return -1;
2894                        }
2895
2896                        if (err < 0)
2897                                break;
2898                }
2899        }
2900
2901        dbi = og_dbi_open(&dbi_config);
2902        if (!dbi) {
2903                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2904                           __func__, __LINE__);
2905                return -1;
2906        }
2907
2908        schedule_root = json_object();
2909        if (!schedule_root) {
2910                og_dbi_close(dbi);
2911                return -1;
2912        }
2913
2914        err = og_dbi_schedule_get_json(dbi, schedule_root,
2915                                       params->task_id, params->id);
2916        og_dbi_close(dbi);
2917
2918        if (err >= 0)
2919                json_dump_callback(schedule_root, og_json_dump_clients, &og_buffer, 0);
2920
2921        json_decref(schedule_root);
2922
2923        return err;
2924}
2925
2926static int og_client_method_not_found(struct og_client *cli)
2927{
2928        /* To meet RFC 7231, this function MUST generate an Allow header field
2929         * containing the correct methods. For example: "Allow: POST\r\n"
2930         */
2931        char buf[] = "HTTP/1.1 405 Method Not Allowed\r\n"
2932                     "Content-Length: 0\r\n\r\n";
2933
2934        send(og_client_socket(cli), buf, strlen(buf), 0);
2935
2936        return -1;
2937}
2938
2939static int og_client_bad_request(struct og_client *cli)
2940{
2941        char buf[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n";
2942
2943        send(og_client_socket(cli), buf, strlen(buf), 0);
2944
2945        return -1;
2946}
2947
2948static int og_client_not_found(struct og_client *cli)
2949{
2950        char buf[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
2951
2952        send(og_client_socket(cli), buf, strlen(buf), 0);
2953
2954        return -1;
2955}
2956
2957static int og_client_not_authorized(struct og_client *cli)
2958{
2959        char buf[] = "HTTP/1.1 401 Unauthorized\r\n"
2960                     "WWW-Authenticate: Basic\r\n"
2961                     "Content-Length: 0\r\n\r\n";
2962
2963        send(og_client_socket(cli), buf, strlen(buf), 0);
2964
2965        return -1;
2966}
2967
2968static int og_server_internal_error(struct og_client *cli)
2969{
2970        char buf[] = "HTTP/1.1 500 Internal Server Error\r\n"
2971                     "Content-Length: 0\r\n\r\n";
2972
2973        send(og_client_socket(cli), buf, strlen(buf), 0);
2974
2975        return -1;
2976}
2977
2978#define OG_MSG_RESPONSE_MAXLEN  65536
2979
2980static int og_client_ok(struct og_client *cli, char *buf_reply)
2981{
2982        char buf[OG_MSG_RESPONSE_MAXLEN] = {};
2983        int err = 0, len;
2984
2985        len = snprintf(buf, sizeof(buf),
2986                       "HTTP/1.1 200 OK\r\nContent-Length: %ld\r\n\r\n%s",
2987                       strlen(buf_reply), buf_reply);
2988        if (len >= (int)sizeof(buf))
2989                err = og_server_internal_error(cli);
2990
2991        send(og_client_socket(cli), buf, strlen(buf), 0);
2992
2993        return err;
2994}
2995
2996int og_client_state_process_payload_rest(struct og_client *cli)
2997{
2998        char buf_reply[OG_MSG_RESPONSE_MAXLEN] = {};
2999        struct og_msg_params params = {};
3000        enum og_rest_method method;
3001        const char *cmd, *body;
3002        json_error_t json_err;
3003        json_t *root = NULL;
3004        int err = 0;
3005
3006        syslog(LOG_DEBUG, "%s:%hu %.32s ...\n",
3007               inet_ntoa(cli->addr.sin_addr),
3008               ntohs(cli->addr.sin_port), cli->buf);
3009
3010        if (!strncmp(cli->buf, "GET", strlen("GET"))) {
3011                method = OG_METHOD_GET;
3012                cmd = cli->buf + strlen("GET") + 2;
3013        } else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
3014                method = OG_METHOD_POST;
3015                cmd = cli->buf + strlen("POST") + 2;
3016        } else
3017                return og_client_method_not_found(cli);
3018
3019        body = strstr(cli->buf, "\r\n\r\n") + 4;
3020
3021        if (strcmp(cli->auth_token, auth_token)) {
3022                syslog(LOG_ERR, "wrong Authentication key\n");
3023                return og_client_not_authorized(cli);
3024        }
3025
3026        if (cli->content_length) {
3027                root = json_loads(body, 0, &json_err);
3028                if (!root) {
3029                        syslog(LOG_ERR, "malformed json line %d: %s\n",
3030                               json_err.line, json_err.text);
3031                        return og_client_not_found(cli);
3032                }
3033        }
3034
3035        if (!strncmp(cmd, "clients", strlen("clients"))) {
3036                if (method != OG_METHOD_POST &&
3037                    method != OG_METHOD_GET)
3038                        return og_client_method_not_found(cli);
3039
3040                if (method == OG_METHOD_POST && !root) {
3041                        syslog(LOG_ERR, "command clients with no payload\n");
3042                        return og_client_bad_request(cli);
3043                }
3044                switch (method) {
3045                case OG_METHOD_POST:
3046                        err = og_cmd_post_clients(root, &params);
3047                        break;
3048                case OG_METHOD_GET:
3049                        err = og_cmd_get_clients(root, &params, buf_reply);
3050                        break;
3051                default:
3052                        return og_client_bad_request(cli);
3053                }
3054        } else if (!strncmp(cmd, "wol", strlen("wol"))) {
3055                if (method != OG_METHOD_POST)
3056                        return og_client_method_not_found(cli);
3057
3058                if (!root) {
3059                        syslog(LOG_ERR, "command wol with no payload\n");
3060                        return og_client_bad_request(cli);
3061                }
3062                err = og_cmd_wol(root, &params);
3063        } else if (!strncmp(cmd, "shell/run", strlen("shell/run"))) {
3064                if (method != OG_METHOD_POST)
3065                        return og_client_method_not_found(cli);
3066
3067                if (!root) {
3068                        syslog(LOG_ERR, "command run with no payload\n");
3069                        return og_client_bad_request(cli);
3070                }
3071                err = og_cmd_run_post(root, &params);
3072        } else if (!strncmp(cmd, "shell/output", strlen("shell/output"))) {
3073                if (method != OG_METHOD_POST)
3074                        return og_client_method_not_found(cli);
3075
3076                if (!root) {
3077                        syslog(LOG_ERR, "command output with no payload\n");
3078                        return og_client_bad_request(cli);
3079                }
3080
3081                err = og_cmd_run_get(root, &params, buf_reply);
3082        } else if (!strncmp(cmd, "session", strlen("session"))) {
3083                if (method != OG_METHOD_POST)
3084                        return og_client_method_not_found(cli);
3085
3086                if (!root) {
3087                        syslog(LOG_ERR, "command session with no payload\n");
3088                        return og_client_bad_request(cli);
3089                }
3090                err = og_cmd_session(root, &params);
[3d253e6]3091        } else if (!strncmp(cmd, "scopes", strlen("scopes"))) {
3092                if (method != OG_METHOD_GET)
3093                        return og_client_method_not_found(cli);
3094
3095                err = og_cmd_scope_get(root, &params, buf_reply);
[04ca20e]3096        } else if (!strncmp(cmd, "poweroff", strlen("poweroff"))) {
3097                if (method != OG_METHOD_POST)
3098                        return og_client_method_not_found(cli);
3099
3100                if (!root) {
3101                        syslog(LOG_ERR, "command poweroff with no payload\n");
3102                        return og_client_bad_request(cli);
3103                }
3104                err = og_cmd_poweroff(root, &params);
3105        } else if (!strncmp(cmd, "reboot", strlen("reboot"))) {
3106                if (method != OG_METHOD_POST)
3107                        return og_client_method_not_found(cli);
3108
3109                if (!root) {
3110                        syslog(LOG_ERR, "command reboot with no payload\n");
3111                        return og_client_bad_request(cli);
3112                }
3113                err = og_cmd_reboot(root, &params);
3114        } else if (!strncmp(cmd, "stop", strlen("stop"))) {
3115                if (method != OG_METHOD_POST)
3116                        return og_client_method_not_found(cli);
3117
3118                if (!root) {
3119                        syslog(LOG_ERR, "command stop with no payload\n");
3120                        return og_client_bad_request(cli);
3121                }
3122                err = og_cmd_stop(root, &params);
3123        } else if (!strncmp(cmd, "refresh", strlen("refresh"))) {
3124                if (method != OG_METHOD_POST)
3125                        return og_client_method_not_found(cli);
3126
3127                if (!root) {
3128                        syslog(LOG_ERR, "command refresh with no payload\n");
3129                        return og_client_bad_request(cli);
3130                }
3131                err = og_cmd_refresh(root, &params);
3132        } else if (!strncmp(cmd, "hardware", strlen("hardware"))) {
3133                if (method != OG_METHOD_POST)
3134                        return og_client_method_not_found(cli);
3135
3136                if (!root) {
3137                        syslog(LOG_ERR, "command hardware with no payload\n");
3138                        return og_client_bad_request(cli);
3139                }
3140                err = og_cmd_hardware(root, &params);
3141        } else if (!strncmp(cmd, "software", strlen("software"))) {
3142                if (method != OG_METHOD_POST)
3143                        return og_client_method_not_found(cli);
3144
3145                if (!root) {
3146                        syslog(LOG_ERR, "command software with no payload\n");
3147                        return og_client_bad_request(cli);
3148                }
3149                err = og_cmd_software(root, &params);
3150        } else if (!strncmp(cmd, "image/create/basic",
3151                            strlen("image/create/basic"))) {
3152                if (method != OG_METHOD_POST)
3153                        return og_client_method_not_found(cli);
3154
3155                if (!root) {
3156                        syslog(LOG_ERR, "command create with no payload\n");
3157                        return og_client_bad_request(cli);
3158                }
3159                err = og_cmd_create_basic_image(root, &params);
3160        } else if (!strncmp(cmd, "image/create/incremental",
3161                            strlen("image/create/incremental"))) {
3162                if (method != OG_METHOD_POST)
3163                        return og_client_method_not_found(cli);
3164
3165                if (!root) {
3166                        syslog(LOG_ERR, "command create with no payload\n");
3167                        return og_client_bad_request(cli);
3168                }
3169                err = og_cmd_create_incremental_image(root, &params);
3170        } else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
3171                if (method != OG_METHOD_POST)
3172                        return og_client_method_not_found(cli);
3173
3174                if (!root) {
3175                        syslog(LOG_ERR, "command create with no payload\n");
3176                        return og_client_bad_request(cli);
3177                }
3178                err = og_cmd_create_image(root, &params);
3179        } else if (!strncmp(cmd, "image/restore/basic",
3180                                strlen("image/restore/basic"))) {
3181                if (method != OG_METHOD_POST)
3182                        return og_client_method_not_found(cli);
3183
3184                if (!root) {
3185                        syslog(LOG_ERR, "command create with no payload\n");
3186                        return og_client_bad_request(cli);
3187                }
3188                err = og_cmd_restore_basic_image(root, &params);
3189        } else if (!strncmp(cmd, "image/restore/incremental",
3190                                strlen("image/restore/incremental"))) {
3191                if (method != OG_METHOD_POST)
3192                        return og_client_method_not_found(cli);
3193
3194                if (!root) {
3195                        syslog(LOG_ERR, "command create with no payload\n");
3196                        return og_client_bad_request(cli);
3197                }
3198                err = og_cmd_restore_incremental_image(root, &params);
3199        } else if (!strncmp(cmd, "image/restore", strlen("image/restore"))) {
3200                if (method != OG_METHOD_POST)
3201                        return og_client_method_not_found(cli);
3202
3203                if (!root) {
3204                        syslog(LOG_ERR, "command create with no payload\n");
3205                        return og_client_bad_request(cli);
3206                }
3207                err = og_cmd_restore_image(root, &params);
3208        } else if (!strncmp(cmd, "setup", strlen("setup"))) {
3209                if (method != OG_METHOD_POST)
3210                        return og_client_method_not_found(cli);
3211
3212                if (!root) {
3213                        syslog(LOG_ERR, "command create with no payload\n");
3214                        return og_client_bad_request(cli);
3215                }
3216                err = og_cmd_setup(root, &params);
3217        } else if (!strncmp(cmd, "run/schedule", strlen("run/schedule"))) {
3218                if (method != OG_METHOD_POST)
3219                        return og_client_method_not_found(cli);
3220
3221                if (!root) {
3222                        syslog(LOG_ERR, "command create with no payload\n");
3223                        return og_client_bad_request(cli);
3224                }
3225
3226                err = og_cmd_run_schedule(root, &params);
3227        } else if (!strncmp(cmd, "task/run", strlen("task/run"))) {
3228                if (method != OG_METHOD_POST)
3229                        return og_client_method_not_found(cli);
3230
3231                if (!root) {
3232                        syslog(LOG_ERR, "command task with no payload\n");
3233                        return og_client_bad_request(cli);
3234                }
3235                err = og_cmd_task_post(root, &params);
3236        } else if (!strncmp(cmd, "schedule/create",
3237                            strlen("schedule/create"))) {
3238                if (method != OG_METHOD_POST)
3239                        return og_client_method_not_found(cli);
3240
3241                if (!root) {
3242                        syslog(LOG_ERR, "command task with no payload\n");
3243                        return og_client_bad_request(cli);
3244                }
3245                err = og_cmd_schedule_create(root, &params);
3246        } else if (!strncmp(cmd, "schedule/delete",
3247                            strlen("schedule/delete"))) {
3248                if (method != OG_METHOD_POST)
3249                        return og_client_method_not_found(cli);
3250
3251                if (!root) {
3252                        syslog(LOG_ERR, "command task with no payload\n");
3253                        return og_client_bad_request(cli);
3254                }
3255                err = og_cmd_schedule_delete(root, &params);
3256        } else if (!strncmp(cmd, "schedule/update",
3257                            strlen("schedule/update"))) {
3258                if (method != OG_METHOD_POST)
3259                        return og_client_method_not_found(cli);
3260
3261                if (!root) {
3262                        syslog(LOG_ERR, "command task with no payload\n");
3263                        return og_client_bad_request(cli);
3264                }
3265                err = og_cmd_schedule_update(root, &params);
3266        } else if (!strncmp(cmd, "schedule/get",
3267                            strlen("schedule/get"))) {
3268                if (method != OG_METHOD_POST)
3269                        return og_client_method_not_found(cli);
3270
3271                err = og_cmd_schedule_get(root, &params, buf_reply);
3272        } else {
3273                syslog(LOG_ERR, "unknown command: %.32s ...\n", cmd);
3274                err = og_client_not_found(cli);
3275        }
3276
3277        if (root)
3278                json_decref(root);
3279
3280        if (err < 0)
3281                return og_client_bad_request(cli);
3282
3283        err = og_client_ok(cli, buf_reply);
3284        if (err < 0) {
3285                syslog(LOG_ERR, "HTTP response to %s:%hu is too large\n",
3286                       inet_ntoa(cli->addr.sin_addr),
3287                       ntohs(cli->addr.sin_port));
3288        }
3289
3290        return err;
3291}
Note: See TracBrowser for help on using the repository browser.