source: ogServer-Git/sources/rest.c @ 3d253e6

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

#980 Add GET /scopes REST request

This patch implements HTTP GET /scopes request which returns the scopes
hierarchy:

Request: HTTP GET /scopes
Response: 200 OK
{

"scope": [

{

"name": "Center 1",
"type": "center",
"id": 1,
"scope": [

{

"name": "Room 1",
"type": "room",
"id": 1,
"scope": [

{

"name": "Computer 1",
"type": "computer",
"id": 1,
"scope": []

},
{

"name": "Computer 3",
"type": "computer",
"id": 2,
"scope": []

}

]

}

]

}

]

}

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