source: ogServer-Git/sources/rest.c @ 96090fd

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

#988 add json configuration file

New configuration file at /opt/opengnsys/cfg/ogserver.json

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