source: ogServer-Git/src/rest.c @ 33b0c6f

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

Add POST /modes REST request

This patch implements HTTP POST /modes request which can change the mode of any
particular scope.

Request: POST /modes
{

"scope": {"id": 1,

"type": "computer"},

"mode": "pxe"

}
Response: 200 OK

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