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

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

#980 Add Virtual status

Since version 1.2.0, OpenGnsys supports ogVDI hypervisor OS. This commit
a new status which indicates that clients are running ogVDI.

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