source: ogServer-Git/src/rest.c @ 96b02b5

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

#990 Use client broadcast address on WoL

Some universities have computers in a different subnet where the
ogServer is, but ogServer WoL functionality only supported to send
packet to its own subnets. This commit solves this.

Now ogServer sends two WoL packets per client, one with the broadcast
address of the interface indicated in the config file, the other with
the broadcast address calculated with the address and netmask of the
client.

To ensure that the second WoL works correctly you must configure
correctly the IP and netmask of the clients. Also, you have to configure
the network of your organization to route WoL packet to the correct
subnet.

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