source: ogServer-Git/src/rest.c @ 927d42b

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

#1043 don't create wol entries when client is connected

Avoids multiple entries of a same client like

{"clients": [{"addr": "192.168.2.230", "state": "WOL_SENT"}, {"addr": "192.168.2.230", "state": "OPG"}]

These can arise when ogserver processes a WoL request for an already
connected client.

When processing the WoL request, search for the target address in the
clients list, if found we avoid creating the wol entry.

  • Property mode set to 100644
File size: 116.9 KB
RevLine 
[04ca20e]1/*
2 * Copyright (C) 2020 Soleta Networks <info@soleta.eu>
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Affero General Public License as published by the
6 * Free Software Foundation, version 3.
7 */
8
9#include "ogAdmServer.h"
10#include "dbi.h"
11#include "utils.h"
12#include "list.h"
13#include "rest.h"
[1f13855]14#include "wol.h"
[866b6c5]15#include "cfg.h"
[04ca20e]16#include "schedule.h"
17#include <ev.h>
18#include <syslog.h>
19#include <sys/ioctl.h>
20#include <ifaddrs.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <jansson.h>
[608709f]25#include <dirent.h>
[04ca20e]26#include <time.h>
[532b081]27#include <stdlib.h>
[139633a]28#include <unistd.h>
29#include <sys/wait.h>
[403e7c3]30#include <sys/statvfs.h>
[04ca20e]31
[48de515]32struct ev_loop *og_loop;
33
[04ca20e]34#define OG_REST_PARAM_ADDR                      (1UL << 0)
35#define OG_REST_PARAM_MAC                       (1UL << 1)
36#define OG_REST_PARAM_WOL_TYPE                  (1UL << 2)
37#define OG_REST_PARAM_RUN_CMD                   (1UL << 3)
38#define OG_REST_PARAM_DISK                      (1UL << 4)
39#define OG_REST_PARAM_PARTITION                 (1UL << 5)
40#define OG_REST_PARAM_REPO                      (1UL << 6)
41#define OG_REST_PARAM_NAME                      (1UL << 7)
42#define OG_REST_PARAM_ID                        (1UL << 8)
43#define OG_REST_PARAM_CODE                      (1UL << 9)
44#define OG_REST_PARAM_TYPE                      (1UL << 10)
45#define OG_REST_PARAM_PROFILE                   (1UL << 11)
46#define OG_REST_PARAM_CACHE                     (1UL << 12)
47#define OG_REST_PARAM_CACHE_SIZE                (1UL << 13)
48#define OG_REST_PARAM_PART_0                    (1UL << 14)
49#define OG_REST_PARAM_PART_1                    (1UL << 15)
50#define OG_REST_PARAM_PART_2                    (1UL << 16)
51#define OG_REST_PARAM_PART_3                    (1UL << 17)
52#define OG_REST_PARAM_SYNC_SYNC                 (1UL << 18)
53#define OG_REST_PARAM_SYNC_DIFF                 (1UL << 19)
54#define OG_REST_PARAM_SYNC_REMOVE               (1UL << 20)
55#define OG_REST_PARAM_SYNC_COMPRESS             (1UL << 21)
56#define OG_REST_PARAM_SYNC_CLEANUP              (1UL << 22)
57#define OG_REST_PARAM_SYNC_CACHE                (1UL << 23)
58#define OG_REST_PARAM_SYNC_CLEANUP_CACHE        (1UL << 24)
59#define OG_REST_PARAM_SYNC_REMOVE_DST           (1UL << 25)
60#define OG_REST_PARAM_SYNC_DIFF_ID              (1UL << 26)
61#define OG_REST_PARAM_SYNC_DIFF_NAME            (1UL << 27)
62#define OG_REST_PARAM_SYNC_PATH                 (1UL << 28)
63#define OG_REST_PARAM_SYNC_METHOD               (1UL << 29)
64#define OG_REST_PARAM_ECHO                      (1UL << 30)
65#define OG_REST_PARAM_TASK                      (1UL << 31)
66#define OG_REST_PARAM_TIME_YEARS                (1UL << 32)
67#define OG_REST_PARAM_TIME_MONTHS               (1UL << 33)
68#define OG_REST_PARAM_TIME_WEEKS                (1UL << 34)
69#define OG_REST_PARAM_TIME_WEEK_DAYS            (1UL << 35)
70#define OG_REST_PARAM_TIME_DAYS                 (1UL << 36)
71#define OG_REST_PARAM_TIME_HOURS                (1UL << 37)
72#define OG_REST_PARAM_TIME_AM_PM                (1UL << 38)
73#define OG_REST_PARAM_TIME_MINUTES              (1UL << 39)
[06af0c2]74#define OG_REST_PARAM_NETMASK                   (1UL << 40)
[33b0c6f]75#define OG_REST_PARAM_SCOPE                     (1UL << 41)
76#define OG_REST_PARAM_MODE                      (1UL << 42)
[29e7641]77#define OG_REST_PARAM_CENTER                    (1UL << 43)
[04ca20e]78
79static LIST_HEAD(client_list);
[1f13855]80static LIST_HEAD(client_wol_list);
[04ca20e]81
82void og_client_add(struct og_client *cli)
83{
84        list_add(&cli->list, &client_list);
85}
86
87static struct og_client *og_client_find(const char *ip)
88{
89        struct og_client *client;
90        struct in_addr addr;
91        int res;
92
93        res = inet_aton(ip, &addr);
94        if (!res) {
95                syslog(LOG_ERR, "Invalid IP string: %s\n", ip);
96                return NULL;
97        }
98
99        list_for_each_entry(client, &client_list, list) {
100                if (client->addr.sin_addr.s_addr == addr.s_addr && client->agent) {
101                        return client;
102                }
103        }
104
105        return NULL;
106}
107
108static const char *og_client_status(const struct og_client *cli)
109{
[a1aaad4]110        switch (cli->last_cmd) {
111        case OG_CMD_UNSPEC:
112        case OG_CMD_PROBE:
113                break;
114        default:
[04ca20e]115                return "BSY";
[a1aaad4]116        }
[04ca20e]117
118        switch (cli->status) {
119        case OG_CLIENT_STATUS_BUSY:
120                return "BSY";
121        case OG_CLIENT_STATUS_OGLIVE:
122                return "OPG";
[c0f5d2c]123        case OG_CLIENT_STATUS_VIRTUAL:
124                return "VDI";
[04ca20e]125        default:
126                return "OFF";
127        }
128}
129
130static bool og_msg_params_validate(const struct og_msg_params *params,
131                                   const uint64_t flags)
132{
133        return (params->flags & flags) == flags;
134}
135
[33b0c6f]136static bool og_flags_validate(const uint64_t flags,
137                              const uint64_t required_flags)
138{
139        return (flags & required_flags) == required_flags;
140}
141
[04ca20e]142static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
143{
144        unsigned int i;
145        json_t *k;
146
147        if (json_typeof(element) != JSON_ARRAY)
148                return -1;
149
150        for (i = 0; i < json_array_size(element); i++) {
151                k = json_array_get(element, i);
152                if (json_typeof(k) != JSON_STRING)
153                        return -1;
154
155                params->ips_array[params->ips_array_len++] =
156                        json_string_value(k);
157
158                params->flags |= OG_REST_PARAM_ADDR;
159        }
160
161        return 0;
162}
163
164static int og_json_parse_partition_setup(json_t *element,
165                                         struct og_msg_params *params)
166{
167        unsigned int i;
168        json_t *k;
169
170        if (json_typeof(element) != JSON_ARRAY)
171                return -1;
172
173        for (i = 0; i < json_array_size(element) && i < OG_PARTITION_MAX; ++i) {
174                k = json_array_get(element, i);
175
176                if (json_typeof(k) != JSON_OBJECT)
177                        return -1;
178
179                if (og_json_parse_partition(k, &params->partition_setup[i],
180                                            OG_PARAM_PART_NUMBER |
181                                            OG_PARAM_PART_CODE |
182                                            OG_PARAM_PART_FILESYSTEM |
183                                            OG_PARAM_PART_SIZE |
184                                            OG_PARAM_PART_FORMAT) < 0)
185                        return -1;
186
187                params->flags |= (OG_REST_PARAM_PART_0 << i);
188        }
189        return 0;
190}
191
192static int og_json_parse_time_params(json_t *element,
193                                     struct og_msg_params *params)
194{
195        const char *key;
196        json_t *value;
197        int err = 0;
198
199        json_object_foreach(element, key, value) {
200                if (!strcmp(key, "years")) {
201                        err = og_json_parse_uint(value, &params->time.years);
202                        params->flags |= OG_REST_PARAM_TIME_YEARS;
203                } else if (!strcmp(key, "months")) {
204                        err = og_json_parse_uint(value, &params->time.months);
205                        params->flags |= OG_REST_PARAM_TIME_MONTHS;
206                } else if (!strcmp(key, "weeks")) {
207                        err = og_json_parse_uint(value, &params->time.weeks);
208                        params->flags |= OG_REST_PARAM_TIME_WEEKS;
209                } else if (!strcmp(key, "week_days")) {
210                        err = og_json_parse_uint(value, &params->time.week_days);
211                        params->flags |= OG_REST_PARAM_TIME_WEEK_DAYS;
212                } else if (!strcmp(key, "days")) {
213                        err = og_json_parse_uint(value, &params->time.days);
214                        params->flags |= OG_REST_PARAM_TIME_DAYS;
215                } else if (!strcmp(key, "hours")) {
216                        err = og_json_parse_uint(value, &params->time.hours);
217                        params->flags |= OG_REST_PARAM_TIME_HOURS;
218                } else if (!strcmp(key, "am_pm")) {
219                        err = og_json_parse_uint(value, &params->time.am_pm);
220                        params->flags |= OG_REST_PARAM_TIME_AM_PM;
221                } else if (!strcmp(key, "minutes")) {
222                        err = og_json_parse_uint(value, &params->time.minutes);
223                        params->flags |= OG_REST_PARAM_TIME_MINUTES;
224                }
225                if (err != 0)
226                        return err;
227        }
228
229        return err;
230}
231
232static const char *og_cmd_to_uri[OG_CMD_MAX] = {
233        [OG_CMD_WOL]            = "wol",
234        [OG_CMD_PROBE]          = "probe",
235        [OG_CMD_SHELL_RUN]      = "shell/run",
236        [OG_CMD_SESSION]        = "session",
237        [OG_CMD_POWEROFF]       = "poweroff",
238        [OG_CMD_REFRESH]        = "refresh",
239        [OG_CMD_REBOOT]         = "reboot",
240        [OG_CMD_STOP]           = "stop",
241        [OG_CMD_HARDWARE]       = "hardware",
242        [OG_CMD_SOFTWARE]       = "software",
243        [OG_CMD_IMAGE_CREATE]   = "image/create",
244        [OG_CMD_IMAGE_RESTORE]  = "image/restore",
245        [OG_CMD_SETUP]          = "setup",
246        [OG_CMD_RUN_SCHEDULE]   = "run/schedule",
[403e7c3]247        [OG_CMD_IMAGES]         = "images",
[04ca20e]248};
249
250static bool og_client_is_busy(const struct og_client *cli,
251                              enum og_cmd_type type)
252{
253        switch (type) {
254        case OG_CMD_REBOOT:
255        case OG_CMD_POWEROFF:
256        case OG_CMD_STOP:
257                break;
258        default:
259                if (cli->last_cmd != OG_CMD_UNSPEC)
260                        return true;
261                break;
262        }
263
264        return false;
265}
266
267int og_send_request(enum og_rest_method method, enum og_cmd_type type,
268                    const struct og_msg_params *params,
269                    const json_t *data)
270{
271        const char *content_type = "Content-Type: application/json";
272        char content [OG_MSG_REQUEST_MAXLEN - 700] = {};
273        char buf[OG_MSG_REQUEST_MAXLEN] = {};
274        unsigned int content_length;
275        char method_str[5] = {};
276        struct og_client *cli;
277        const char *uri;
278        unsigned int i;
279        int client_sd;
280
281        if (method == OG_METHOD_GET)
282                snprintf(method_str, 5, "GET");
283        else if (method == OG_METHOD_POST)
284                snprintf(method_str, 5, "POST");
285        else
286                return -1;
287
288        if (!data)
289                content_length = 0;
290        else
291                content_length = json_dumpb(data, content,
292                                            OG_MSG_REQUEST_MAXLEN - 700,
293                                            JSON_COMPACT);
294
295        uri = og_cmd_to_uri[type];
296        snprintf(buf, OG_MSG_REQUEST_MAXLEN,
297                 "%s /%s HTTP/1.1\r\nContent-Length: %d\r\n%s\r\n\r\n%s",
298                 method_str, uri, content_length, content_type, content);
299
300        for (i = 0; i < params->ips_array_len; i++) {
301                cli = og_client_find(params->ips_array[i]);
302                if (!cli)
303                        continue;
304
305                if (og_client_is_busy(cli, type))
306                        continue;
307
308                client_sd = cli->io.fd;
309                if (client_sd < 0) {
310                        syslog(LOG_INFO, "Client %s not conected\n",
311                               params->ips_array[i]);
312                        continue;
313                }
314
315                if (send(client_sd, buf, strlen(buf), 0) < 0)
316                        continue;
317
318                cli->last_cmd = type;
319        }
320
[1c52b78]321        json_decref((json_t *)data);
322
[04ca20e]323        return 0;
324}
325
326static int og_cmd_post_clients(json_t *element, struct og_msg_params *params)
327{
328        const char *key;
329        json_t *value;
330        int err = 0;
331
332        if (json_typeof(element) != JSON_OBJECT)
333                return -1;
334
335        json_object_foreach(element, key, value) {
336                if (!strcmp(key, "clients"))
337                        err = og_json_parse_clients(value, params);
338
339                if (err < 0)
[e7e80cd]340                        return err;
[04ca20e]341        }
342
343        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
344                return -1;
345
346        return og_send_request(OG_METHOD_POST, OG_CMD_PROBE, params, NULL);
347}
348
349struct og_buffer {
350        char    *data;
351        int     len;
352};
353
[49fc6c5]354#define OG_MSG_RESPONSE_MAXLEN  262144
[2c6cef7]355
[04ca20e]356static int og_json_dump_clients(const char *buffer, size_t size, void *data)
357{
358        struct og_buffer *og_buffer = (struct og_buffer *)data;
359
[2c6cef7]360        if (size >= OG_MSG_RESPONSE_MAXLEN - og_buffer->len) {
361                syslog(LOG_ERR, "Response JSON body is too large\n");
362                return -1;
363        }
364
[04ca20e]365        memcpy(og_buffer->data + og_buffer->len, buffer, size);
366        og_buffer->len += size;
367
368        return 0;
369}
370
[c05f134]371static int og_json_client_append(json_t *array, struct og_client *client)
372{
373        json_t *addr, *state, *object;
374
375        object = json_object();
376        if (!object)
377                return -1;
378
379        addr = json_string(inet_ntoa(client->addr.sin_addr));
380        if (!addr) {
381                json_decref(object);
382                return -1;
383        }
384        json_object_set_new(object, "addr", addr);
385        state = json_string(og_client_status(client));
386        if (!state) {
387                json_decref(object);
388                return -1;
389        }
390        json_object_set_new(object, "state", state);
391        json_array_append_new(array, object);
392
393        return 0;
394}
395
[1f13855]396static int og_json_client_wol_append(json_t *array,
397                                     struct og_client_wol *cli_wol)
398{
399        json_t *addr, *state, *object;
400
401        object = json_object();
402        if (!object)
403                return -1;
404
405        addr = json_string(inet_ntoa(cli_wol->addr));
406        if (!addr) {
407                json_decref(object);
408                return -1;
409        }
410        json_object_set_new(object, "addr", addr);
411        state = json_string(og_client_wol_status(cli_wol));
412        if (!state) {
413                json_decref(object);
414                return -1;
415        }
416        json_object_set_new(object, "state", state);
417        json_array_append_new(array, object);
418
419        return 0;
420}
421
[04ca20e]422static int og_cmd_get_clients(json_t *element, struct og_msg_params *params,
423                              char *buffer_reply)
424{
425        struct og_buffer og_buffer = {
426                .data   = buffer_reply,
427        };
[1f13855]428        struct og_client_wol *cli_wol;
429        struct og_client *client;
[c05f134]430        json_t *array, *root;
[04ca20e]431
432        array = json_array();
433        if (!array)
434                return -1;
435
[1f13855]436        list_for_each_entry(cli_wol, &client_wol_list, list) {
437                if (og_json_client_wol_append(array, cli_wol) < 0) {
438                        json_decref(array);
439                        return -1;
440                }
441        }
442
[04ca20e]443        list_for_each_entry(client, &client_list, list) {
444                if (!client->agent)
445                        continue;
446
[c05f134]447                if (og_json_client_append(array, client) < 0) {
[04ca20e]448                        json_decref(array);
449                        return -1;
450                }
451        }
[c05f134]452
[04ca20e]453        root = json_pack("{s:o}", "clients", array);
454        if (!root) {
455                json_decref(array);
456                return -1;
457        }
458
[2c6cef7]459        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
460                json_decref(root);
461                return -1;
462        }
463
[04ca20e]464        json_decref(root);
465
466        return 0;
467}
468
469static int og_json_parse_type(json_t *element, struct og_msg_params *params)
470{
471        const char *type;
472
473        if (json_typeof(element) != JSON_STRING)
474                return -1;
475
476        params->wol_type = json_string_value(element);
477
478        type = json_string_value(element);
479        if (!strcmp(type, "unicast"))
480                params->wol_type = "2";
481        else if (!strcmp(type, "broadcast"))
482                params->wol_type = "1";
483
484        params->flags |= OG_REST_PARAM_WOL_TYPE;
485
486        return 0;
487}
488
[1f13855]489struct og_client_wol *og_client_wol_find(const struct in_addr *addr)
490{
491        struct og_client_wol *cli_wol;
492
493        list_for_each_entry(cli_wol, &client_wol_list, list) {
494                if (cli_wol->addr.s_addr == addr->s_addr)
495                        return cli_wol;
496        }
497
498        return NULL;
499}
500
[04ca20e]501static int og_cmd_wol(json_t *element, struct og_msg_params *params)
502{
[e4cb91b]503        char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
[1f13855]504        struct og_client_wol *cli_wol;
[e4cb91b]505        int ips_str_len = 0;
[1f13855]506        struct in_addr addr;
[e4cb91b]507        const char *msglog;
508        struct og_dbi *dbi;
509        int err = 0, i = 0;
510        dbi_result result;
[04ca20e]511        const char *key;
512        json_t *value;
513
514        if (json_typeof(element) != JSON_OBJECT)
515                return -1;
516
517        json_object_foreach(element, key, value) {
518                if (!strcmp(key, "clients")) {
[e4cb91b]519                        err = og_json_parse_clients(value, params);
[04ca20e]520                } else if (!strcmp(key, "type")) {
521                        err = og_json_parse_type(value, params);
522                }
523
524                if (err < 0)
[e7e80cd]525                        return err;
[04ca20e]526        }
527        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
528                                            OG_REST_PARAM_WOL_TYPE))
529                return -1;
530
[e4cb91b]531        for (i = 0; i < params->ips_array_len; ++i) {
532                ips_str_len += snprintf(ips_str + ips_str_len,
533                                        sizeof(ips_str) - ips_str_len,
534                                        "'%s',", params->ips_array[i]);
535        }
536        ips_str[ips_str_len - 1] = '\0';
537
538        dbi = og_dbi_open(&ogconfig.db);
539        if (!dbi) {
540                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
541                       __func__, __LINE__);
542                return -1;
543        }
544
545        result = dbi_conn_queryf(dbi->conn,
[e6c2c26]546                                 "SELECT ordenadores.ip, ordenadores.mac, "
547                                        "aulas.netmask "
548                                 "FROM   ordenadores "
549                                 "INNER JOIN aulas "
550                                         "ON ordenadores.idaula = aulas.idaula "
551                                 "WHERE  ordenadores.ip IN (%s)",
552                                 ips_str);
[e4cb91b]553        if (!result) {
554                dbi_conn_error(dbi->conn, &msglog);
555                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
556                       __func__, __LINE__, msglog);
557                og_dbi_close(dbi);
558                return -1;
559        }
560
561        for (i = 0; dbi_result_next_row(result); i++) {
562                params->ips_array[i] = dbi_result_get_string_copy(result, "ip");
563                params->mac_array[i] = dbi_result_get_string_copy(result, "mac");
[e6c2c26]564                params->netmask_array[i] = dbi_result_get_string_copy(result, "netmask");
[e4cb91b]565        }
566
567        dbi_result_free(result);
568        og_dbi_close(dbi);
569
[a71cba4]570        if (i == 0)
571                return 0;
572
[1f13855]573        for (i = 0; i < params->ips_array_len; i++) {
[927d42b]574                if (og_client_find(params->ips_array[i]))
575                        continue;
576
[1f13855]577                if (inet_aton(params->ips_array[i], &addr) < 0)
578                        return -1;
579
580                cli_wol = og_client_wol_find(&addr);
581                if (cli_wol) {
582                        og_client_wol_refresh(cli_wol);
583                        continue;
584                }
585
586                cli_wol = og_client_wol_create(&addr);
587                if (!cli_wol)
588                        return -1;
589
590                list_add_tail(&cli_wol->list, &client_wol_list);
591        }
592
[04ca20e]593        if (!Levanta((char **)params->ips_array, (char **)params->mac_array,
[a71cba4]594                     (char **)params->netmask_array, i,
[06af0c2]595                     (char *)params->wol_type))
[04ca20e]596                return -1;
597
[a46b69b]598        for (i = 0; i < params->ips_array_len; ++i) {
599                free((void *)params->ips_array[i]);
600                free((void *)params->mac_array[i]);
601                free((void *)params->netmask_array[i]);
602        }
603
[04ca20e]604        return 0;
605}
606
607static int og_json_parse_run(json_t *element, struct og_msg_params *params)
608{
609        if (json_typeof(element) != JSON_STRING)
610                return -1;
611
612        snprintf(params->run_cmd, sizeof(params->run_cmd), "%s",
613                 json_string_value(element));
614
615        params->flags |= OG_REST_PARAM_RUN_CMD;
616
617        return 0;
618}
619
620static int og_cmd_run_post(json_t *element, struct og_msg_params *params)
621{
622        json_t *value, *clients;
623        const char *key;
624        unsigned int i;
625        int err = 0;
626
627        if (json_typeof(element) != JSON_OBJECT)
628                return -1;
629
630        json_object_foreach(element, key, value) {
631                if (!strcmp(key, "clients"))
632                        err = og_json_parse_clients(value, params);
633                else if (!strcmp(key, "run"))
634                        err = og_json_parse_run(value, params);
635                else if (!strcmp(key, "echo")) {
636                        err = og_json_parse_bool(value, &params->echo);
637                        params->flags |= OG_REST_PARAM_ECHO;
638                }
639
640                if (err < 0)
[e7e80cd]641                        return err;
[04ca20e]642        }
643
644        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
645                                            OG_REST_PARAM_RUN_CMD |
646                                            OG_REST_PARAM_ECHO))
647                return -1;
648
649        clients = json_copy(element);
650        json_object_del(clients, "clients");
651
652        err = og_send_request(OG_METHOD_POST, OG_CMD_SHELL_RUN, params, clients);
653        if (err < 0)
654                return err;
655
656        for (i = 0; i < params->ips_array_len; i++) {
657                char filename[4096];
658                FILE *f;
659
660                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
661                f = fopen(filename, "wt");
662                fclose(f);
663        }
664
665        return 0;
666}
667
668static int og_cmd_run_get(json_t *element, struct og_msg_params *params,
669                          char *buffer_reply)
670{
671        struct og_buffer og_buffer = {
672                .data   = buffer_reply,
673        };
674        json_t *root, *value, *array;
675        const char *key;
676        unsigned int i;
677        int err = 0;
678
679        if (json_typeof(element) != JSON_OBJECT)
680                return -1;
681
682        json_object_foreach(element, key, value) {
683                if (!strcmp(key, "clients"))
684                        err = og_json_parse_clients(value, params);
685
686                if (err < 0)
687                        return err;
688        }
689
690        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
691                return -1;
692
693        array = json_array();
694        if (!array)
695                return -1;
696
697        for (i = 0; i < params->ips_array_len; i++) {
698                json_t *object, *output, *addr;
699                char data[4096] = {};
700                char filename[4096];
701                int fd, numbytes;
702
703                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
704
705                fd = open(filename, O_RDONLY);
706                if (!fd)
707                        return -1;
708
709                numbytes = read(fd, data, sizeof(data));
710                if (numbytes < 0) {
711                        close(fd);
712                        return -1;
713                }
714                data[sizeof(data) - 1] = '\0';
715                close(fd);
716
717                object = json_object();
718                if (!object) {
719                        json_decref(array);
720                        return -1;
721                }
722                addr = json_string(params->ips_array[i]);
723                if (!addr) {
724                        json_decref(object);
725                        json_decref(array);
726                        return -1;
727                }
728                json_object_set_new(object, "addr", addr);
729
730                output = json_string(data);
731                if (!output) {
732                        json_decref(object);
733                        json_decref(array);
734                        return -1;
735                }
736                json_object_set_new(object, "output", output);
737
738                json_array_append_new(array, object);
739        }
740
741        root = json_pack("{s:o}", "clients", array);
742        if (!root)
743                return -1;
744
[2c6cef7]745        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
746                json_decref(root);
747                return -1;
748        }
749
[04ca20e]750        json_decref(root);
751
752        return 0;
753}
754
755static int og_cmd_session(json_t *element, struct og_msg_params *params)
756{
757        json_t *clients, *value;
758        const char *key;
759        int err = 0;
760
761        if (json_typeof(element) != JSON_OBJECT)
762                return -1;
763
764        json_object_foreach(element, key, value) {
765                if (!strcmp(key, "clients")) {
766                        err = og_json_parse_clients(value, params);
767                } else if (!strcmp(key, "disk")) {
768                        err = og_json_parse_string(value, &params->disk);
769                        params->flags |= OG_REST_PARAM_DISK;
770                } else if (!strcmp(key, "partition")) {
771                        err = og_json_parse_string(value, &params->partition);
772                        params->flags |= OG_REST_PARAM_PARTITION;
773                }
774
775                if (err < 0)
776                        return err;
777        }
778
779        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
780                                            OG_REST_PARAM_DISK |
781                                            OG_REST_PARAM_PARTITION))
782                return -1;
783
784        clients = json_copy(element);
785        json_object_del(clients, "clients");
786
787        return og_send_request(OG_METHOD_POST, OG_CMD_SESSION, params, clients);
788}
789
[7f5ab4a]790static int og_cmd_get_session(json_t *element, struct og_msg_params *params,
791                              char *buffer_reply)
792{
793        json_t *value, *root, *array, *item;
794        const char *key, *msglog, *os_name;
795        unsigned int disk, partition;
796        struct og_dbi *dbi;
797        dbi_result result;
798        int err = 0;
799
800        struct og_buffer og_buffer = {
801                .data = buffer_reply
802        };
803
804        json_object_foreach(element, key, value) {
805                if (!strcmp(key, "client"))
806                        err = og_json_parse_clients(value, params);
807                else
808                        err = -1;
809
810                if (err < 0)
811                        return err;
812        }
813
814        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
815                return -1;
816
817        dbi = og_dbi_open(&ogconfig.db);
818        if (!dbi) {
819                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
820                       __func__, __LINE__);
821                return -1;
822        }
823
824        result = dbi_conn_queryf(dbi->conn,
825                                 "SELECT op.numdisk, op.numpar, nom.nombreso "
826                                 "FROM ordenadores o "
827                                 "INNER JOIN ordenadores_particiones op "
828                                 "    ON o.idordenador = op.idordenador "
829                                 "INNER JOIN nombresos nom "
830                                 "    ON op.idnombreso = nom.idnombreso "
831                                 "WHERE o.ip = '%s'",
832                                 params->ips_array[0]);
833        if (!result) {
834                dbi_conn_error(dbi->conn, &msglog);
835                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
836                       __func__, __LINE__, msglog);
837                og_dbi_close(dbi);
838                return -1;
839        }
840
841        array = json_array();
842        if (!array) {
843                dbi_result_free(result);
844                og_dbi_close(dbi);
845                return -1;
846        }
847
848        while (dbi_result_next_row(result)) {
849                item = json_object();
850                if (!item) {
851                        dbi_result_free(result);
852                        og_dbi_close(dbi);
853                        json_decref(array);
854                        return -1;
855                }
856
857                disk = dbi_result_get_uint(result, "numdisk");
858                partition = dbi_result_get_uint(result, "numpar");
859                os_name = dbi_result_get_string(result, "nombreso");
860
861                json_object_set_new(item, "disk", json_integer(disk));
862                json_object_set_new(item, "partition", json_integer(partition));
863                json_object_set_new(item, "name", json_string(os_name));
864                json_array_append_new(array, item);
865        }
866
867        dbi_result_free(result);
868        og_dbi_close(dbi);
869
870        root = json_object();
871        if (!root){
872                json_decref(array);
873                return -1;
874        }
875
876        json_object_set_new(root, "sessions", array);
877
[2c6cef7]878        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
879                json_decref(root);
880                return -1;
881        }
882
[7f5ab4a]883        json_decref(root);
884        return 0;
885}
886
[04ca20e]887static int og_cmd_poweroff(json_t *element, struct og_msg_params *params)
888{
889        const char *key;
890        json_t *value;
891        int err = 0;
892
893        if (json_typeof(element) != JSON_OBJECT)
894                return -1;
895
896        json_object_foreach(element, key, value) {
897                if (!strcmp(key, "clients"))
898                        err = og_json_parse_clients(value, params);
899
900                if (err < 0)
[e7e80cd]901                        return err;
[04ca20e]902        }
903
904        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
905                return -1;
906
907        return og_send_request(OG_METHOD_POST, OG_CMD_POWEROFF, params, NULL);
908}
909
910static int og_cmd_refresh(json_t *element, struct og_msg_params *params)
911{
912        const char *key;
913        json_t *value;
914        int err = 0;
915
916        if (json_typeof(element) != JSON_OBJECT)
917                return -1;
918
919        json_object_foreach(element, key, value) {
920                if (!strcmp(key, "clients"))
921                        err = og_json_parse_clients(value, params);
922
923                if (err < 0)
[e7e80cd]924                        return err;
[04ca20e]925        }
926
927        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
928                return -1;
929
930        return og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, params, NULL);
931}
932
933static int og_cmd_reboot(json_t *element, struct og_msg_params *params)
934{
935        const char *key;
936        json_t *value;
937        int err = 0;
938
939        if (json_typeof(element) != JSON_OBJECT)
940                return -1;
941
942        json_object_foreach(element, key, value) {
943                if (!strcmp(key, "clients"))
944                        err = og_json_parse_clients(value, params);
945
946                if (err < 0)
[e7e80cd]947                        return err;
[04ca20e]948        }
949
950        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
951                return -1;
952
953        return og_send_request(OG_METHOD_POST, OG_CMD_REBOOT, params, NULL);
954}
955
[85d0928]956#define OG_TFTP_TMPL_PATH_UEFI "/opt/opengnsys/tftpboot/grub/templates"
[608709f]957#define OG_TFTP_TMPL_PATH "/opt/opengnsys/tftpboot/menu.lst/templates"
958
959static int og_cmd_get_modes(json_t *element, struct og_msg_params *params,
960                            char *buffer_reply)
961{
962        struct og_buffer og_buffer = {
963                .data = buffer_reply
964        };
965        json_t *root, *modes;
966        struct dirent *dent;
967        DIR *d = NULL;
968
969        root = json_object();
970        if (!root)
971                return -1;
972
973        modes = json_array();
974        if (!modes) {
975                json_decref(root);
976                return -1;
977        }
978
979        d = opendir(OG_TFTP_TMPL_PATH);
980        if (!d) {
981                json_decref(modes);
982                json_decref(root);
983                syslog(LOG_ERR, "Cannot open directory %s\n",
984                       OG_TFTP_TMPL_PATH);
985                return -1;
986        }
987
988        dent = readdir(d);
989        while (dent) {
990                if (dent->d_type != DT_REG) {
991                        dent = readdir(d);
992                        continue;
993                }
994                json_array_append_new(modes, json_string(dent->d_name));
995                dent = readdir(d);
996        }
997        json_object_set_new(root, "modes", modes);
[2c6cef7]998
999        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
1000                json_decref(root);
1001                return -1;
1002        }
1003
[608709f]1004        json_decref(root);
[e54c5ca]1005        closedir(d);
[608709f]1006
1007        return 0;
1008}
1009
[532b081]1010static int og_change_db_mode(struct og_dbi *dbi, const char *mac,
1011                             const char * mode)
1012{
1013        const char *msglog;
1014        dbi_result result;
1015
1016        result = dbi_conn_queryf(dbi->conn,
1017                                 "UPDATE ordenadores SET arranque='%s' "
1018                                 "WHERE mac='%s'",
1019                                 mode, mac);
1020
1021        if (!result) {
1022                dbi_conn_error(dbi->conn, &msglog);
1023                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1024                       __func__, __LINE__, msglog);
1025                return -1;
1026        }
1027
1028        dbi_result_free(result);
1029        return 0;
1030}
1031
1032static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
[4ae9903]1033                              const char *mode, const char *template_name)
[532b081]1034{
1035        char filename[PATH_MAX + 1] = "/tmp/mode_params_XXXXXX";
[1855b68]1036        char cmd_params[16384] = {};
1037        char params[4096] = "\0";
[532b081]1038        const char *msglog;
1039        dbi_result result;
1040        unsigned int i;
1041        int numbytes;
[139633a]1042        int status;
[532b081]1043        int fd;
1044
1045        result = dbi_conn_queryf(dbi->conn,
1046                "SELECT ' LANG=%s', ' ip=', CONCAT_WS(':', ordenadores.ip, (SELECT (@serverip:=ipserveradm) FROM entornos LIMIT 1), aulas.router, aulas.netmask, ordenadores.nombreordenador, ordenadores.netiface, 'none'), ' group=', REPLACE(TRIM(aulas.nombreaula), ' ', '_'), ' ogrepo=', (@repoip:=IFNULL(repositorios.ip, '')), ' oglive=', @serverip, ' oglog=', @serverip, ' ogshare=', @serverip, ' oglivedir=', ordenadores.oglivedir, ' ogprof=', IF(ordenadores.idordenador=aulas.idordprofesor, 'true', 'false'), IF(perfileshard.descripcion<>'', CONCAT(' hardprofile=', REPLACE(TRIM(perfileshard.descripcion), ' ', '_')), ''), IF(aulas.ntp<>'', CONCAT(' ogntp=', aulas.ntp), ''), IF(aulas.dns<>'', CONCAT(' ogdns=', aulas.dns), ''), IF(aulas.proxy<>'', CONCAT(' ogproxy=', aulas.proxy), ''), IF(entidades.ogunit=1 AND NOT centros.directorio='', CONCAT(' ogunit=', centros.directorio), ''), CASE WHEN menus.resolucion IS NULL THEN '' WHEN menus.resolucion <= '999' THEN CONCAT(' vga=', menus.resolucion) WHEN menus.resolucion LIKE '%:%' THEN CONCAT(' video=', menus.resolucion) ELSE menus.resolucion END FROM ordenadores JOIN aulas USING(idaula) JOIN centros USING(idcentro) JOIN entidades USING(identidad) LEFT JOIN repositorios USING(idrepositorio) LEFT JOIN perfileshard USING(idperfilhard) LEFT JOIN menus USING(idmenu) WHERE ordenadores.mac='%s'", getenv("LANG"), mac);
1047
1048        if (dbi_result_get_numrows(result) != 1) {
1049                dbi_conn_error(dbi->conn, &msglog);
1050                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1051                       __FILE__, __LINE__, msglog);
1052                dbi_result_free(result);
1053                return -1;
1054        }
1055        dbi_result_next_row(result);
1056
1057        for (i = 1; i <= dbi_result_get_numfields(result); ++i)
1058                strcat(params, dbi_result_get_string_idx(result, i));
1059
1060        dbi_result_free(result);
1061
1062        snprintf(cmd_params, sizeof(cmd_params),
1063                 "MODE_FILE='%s'\nMAC='%s'\nDATA='%s'\n"
1064                 "MODE='PERM'\nTEMPLATE_NAME='%s'",
1065                 mode, mac, params, template_name);
1066
1067        fd = mkstemp(filename);
1068        if (fd < 0) {
1069                syslog(LOG_ERR, "cannot generate temp file (%s:%d)\n",
1070                       __func__, __LINE__);
1071                return -1;
1072        }
1073
1074        numbytes = write(fd, cmd_params, strlen(cmd_params) + 1);
1075        close(fd);
1076
1077        if (numbytes < 0) {
1078                syslog(LOG_ERR, "cannot write file\n");
1079                unlink(filename);
1080                return -1;
1081        }
1082
[139633a]1083        if (fork() == 0) {
1084                execlp("/bin/bash", "/bin/bash",
1085                       "/opt/opengnsys/bin/setclientmode", filename, NULL);
[5286c93]1086                syslog(LOG_ERR, "failed script execution (%s:%d)\n",
1087                       __func__, __LINE__);
1088                exit(EXIT_FAILURE);
[139633a]1089        } else {
1090                wait(&status);
1091        }
[532b081]1092        unlink(filename);
[139633a]1093
1094        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
[532b081]1095                syslog(LOG_ERR, "failed script execution (%s:%d)\n",
1096                       __func__, __LINE__);
1097                return -1;
1098        }
1099
1100        if (og_change_db_mode(dbi, mac, mode) < 0) {
1101                syslog(LOG_ERR, "failed to change db mode (%s:%d)\n",
1102                       __func__, __LINE__);
1103                return -1;
1104        }
1105
1106        return 0;
1107}
1108
[33b0c6f]1109static int og_cmd_post_modes(json_t *element, struct og_msg_params *params)
1110{
[4ae9903]1111        char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
[85d0928]1112        char template_file_uefi[PATH_MAX + 1] = {};
[532b081]1113        char template_file[PATH_MAX + 1] = {};
1114        char template_name[PATH_MAX + 1] = {};
1115        char first_line[PATH_MAX + 1] = {};
[4ae9903]1116        const char *mode_str, *mac;
1117        int ips_str_len = 0;
[33b0c6f]1118        struct og_dbi *dbi;
1119        uint64_t flags = 0;
1120        dbi_result result;
1121        const char *key;
1122        json_t *value;
1123        int err = 0;
[532b081]1124        FILE *f;
[4ae9903]1125        int i;
[33b0c6f]1126
1127        json_object_foreach(element, key, value) {
[4ae9903]1128                if (!strcmp(key, "clients")) {
1129                        err = og_json_parse_clients(value, params);
[33b0c6f]1130                } else if (!strcmp(key, "mode")) {
1131                        err = og_json_parse_string(value, &mode_str);
1132                        flags |= OG_REST_PARAM_MODE;
1133                } else {
1134                        err = -1;
1135                }
1136
1137                if (err < 0)
[e7e80cd]1138                        return err;
[33b0c6f]1139        }
1140
[4ae9903]1141        if (!og_flags_validate(flags, OG_REST_PARAM_MODE) ||
1142            !og_msg_params_validate(params, OG_REST_PARAM_ADDR))
[33b0c6f]1143                return -1;
1144
[532b081]1145        snprintf(template_file, sizeof(template_file), "%s/%s",
1146                 OG_TFTP_TMPL_PATH, mode_str);
1147        f = fopen(template_file, "r");
1148        if (!f) {
[85d0928]1149                syslog(LOG_WARNING, "cannot open file %s (%s:%d). Trying UEFI template instead.\n",
1150                       template_file, __func__, __LINE__);
1151
1152                snprintf(template_file_uefi, sizeof(template_file_uefi), "%s/%s",
1153                         OG_TFTP_TMPL_PATH_UEFI, mode_str);
1154                f = fopen(template_file_uefi, "r");
1155                if (!f) {
1156                        syslog(LOG_ERR, "cannot open file %s (%s:%d). No template found.\n",
1157                               template_file_uefi, __func__, __LINE__);
1158                        return -1;
1159                }
[33b0c6f]1160        }
1161
[532b081]1162        if (!fgets(first_line, sizeof(first_line), f)) {
1163                fclose(f);
1164                syslog(LOG_ERR, "cannot read file (%s:%d)\n",
[33b0c6f]1165                       __func__, __LINE__);
1166                return -1;
1167        }
1168
[532b081]1169        fclose(f);
1170
1171        if (sscanf(first_line, "##NO-TOCAR-ESTA-LINEA %s", template_name) != 1) {
1172                syslog(LOG_ERR, "malformed template: %s", first_line);
1173                return -1;
1174        }
1175
[4ae9903]1176        for (i = 0; i < params->ips_array_len; ++i) {
1177                ips_str_len += snprintf(ips_str + ips_str_len,
1178                                        sizeof(ips_str) - ips_str_len,
1179                                        "'%s',", params->ips_array[i]);
1180        }
1181        ips_str[ips_str_len - 1] = '\0';
1182
[fe1ce97]1183        dbi = og_dbi_open(&ogconfig.db);
[532b081]1184        if (!dbi) {
1185                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
1186                       __func__, __LINE__);
[33b0c6f]1187                return -1;
1188        }
1189
[532b081]1190        result = dbi_conn_queryf(dbi->conn,
1191                                 "SELECT mac FROM ordenadores "
[4ae9903]1192                                 "WHERE ip IN (%s)", ips_str);
[532b081]1193
1194        while (dbi_result_next_row(result)) {
1195                mac = dbi_result_get_string(result, "mac");
[4ae9903]1196                err = og_set_client_mode(dbi, mac, mode_str, template_name);
[532b081]1197                if (err != 0) {
1198                        dbi_result_free(result);
1199                        og_dbi_close(dbi);
1200                        return -1;
1201                }
1202        }
1203
[33b0c6f]1204        dbi_result_free(result);
1205        og_dbi_close(dbi);
1206
1207        return 0;
1208}
1209
[b59ff7c]1210static int og_cmd_get_client_setup(json_t *element,
1211                                   struct og_msg_params *params,
1212                                   char *buffer_reply)
1213{
1214        json_t *value, *root, *partitions_array, *partition_json;
1215        const char *key, *msglog;
1216        unsigned int len_part;
1217        struct og_dbi *dbi;
1218        dbi_result result;
1219        int err = 0;
1220
1221        struct og_buffer og_buffer = {
1222                .data = buffer_reply
1223        };
1224
1225        struct {
1226                int disk;
1227                int number;
1228                int code;
[4d2e1dd]1229                uint64_t size;
[b59ff7c]1230                int filesystem;
1231                int format;
1232                int os;
1233                int used_size;
1234                int image;
1235                int software;
1236        } partition;
1237
1238        json_object_foreach(element, key, value) {
1239                if (!strcmp(key, "client")) {
1240                        err = og_json_parse_clients(value, params);
1241                }
1242
1243                if (err < 0)
[e7e80cd]1244                        return err;
[b59ff7c]1245        }
1246
1247        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1248                return -1;
1249
1250        if (params->ips_array_len != 1)
1251                return -1;
1252
1253        root = json_object();
1254        if (!root)
1255                return -1;
1256
1257        partitions_array = json_array();
1258        if (!partitions_array) {
1259                json_decref(root);
1260                return -1;
1261        }
1262        json_object_set_new(root, "partitions", partitions_array);
1263
[fe1ce97]1264        dbi = og_dbi_open(&ogconfig.db);
[b59ff7c]1265        if (!dbi) {
1266                json_decref(root);
1267                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
1268                       __func__, __LINE__);
1269                return -1;
1270        }
1271
1272        result = dbi_conn_queryf(dbi->conn,
1273                                 "SELECT numdisk, numpar, codpar, tamano, "
1274                                 "       uso, idsistemafichero, idnombreso, "
1275                                 "       idimagen, idperfilsoft "
1276                                 "FROM ordenadores_particiones "
1277                                 "INNER JOIN ordenadores "
1278                                 "ON ordenadores.idordenador = ordenadores_particiones.idordenador "
1279                                 "WHERE ordenadores.ip='%s'",
1280                                 params->ips_array[0]);
1281        if (!result) {
1282                json_decref(root);
1283                dbi_conn_error(dbi->conn, &msglog);
1284                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1285                       __func__, __LINE__, msglog);
1286                og_dbi_close(dbi);
1287                return -1;
1288        }
1289
1290        len_part = 0;
[ff71a2a]1291        /* partition 0 represents the full disk, hence OG_PARTITION_MAX + 1. */
1292        while (dbi_result_next_row(result) && len_part < OG_PARTITION_MAX + 1) {
[b59ff7c]1293                partition.disk = dbi_result_get_int(result, "numdisk");
1294                partition.number = dbi_result_get_int(result, "numpar");
1295                partition.code = dbi_result_get_int(result, "codpar");
[4d2e1dd]1296                partition.size = dbi_result_get_longlong(result, "tamano");
[b59ff7c]1297                partition.used_size = dbi_result_get_int(result, "uso");
1298                partition.filesystem = dbi_result_get_int(result, "idsistemafichero");
1299                partition.os = dbi_result_get_int(result, "idnombreso");
1300                partition.image = dbi_result_get_int(result, "idimagen");
1301                partition.software = dbi_result_get_int(result, "idperfilsoft");
1302
1303                partition_json = json_object();
1304                if (!partition_json) {
1305                        json_decref(root);
1306                        dbi_result_free(result);
1307                        og_dbi_close(dbi);
1308                        return -1;
1309                }
1310
1311                json_object_set_new(partition_json, "disk",
1312                                    json_integer(partition.disk));
1313                json_object_set_new(partition_json, "partition",
1314                                    json_integer(partition.number));
1315                json_object_set_new(partition_json, "code",
1316                                    json_integer(partition.code));
1317                json_object_set_new(partition_json, "size",
1318                                    json_integer(partition.size));
1319                json_object_set_new(partition_json, "used_size",
1320                                    json_integer(partition.used_size));
1321                json_object_set_new(partition_json, "filesystem",
1322                                    json_integer(partition.filesystem));
1323                json_object_set_new(partition_json, "os",
1324                                    json_integer(partition.os));
1325                json_object_set_new(partition_json, "image",
1326                                    json_integer(partition.image));
1327                json_object_set_new(partition_json, "software",
1328                                    json_integer(partition.software));
1329                json_array_append_new(partitions_array, partition_json);
1330
1331                ++len_part;
1332        }
1333
1334        dbi_result_free(result);
1335        og_dbi_close(dbi);
1336
[2c6cef7]1337        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
1338                json_decref(root);
1339                return -1;
1340        }
1341
[b59ff7c]1342        json_decref(root);
1343        return 0;
1344}
1345
[af47a08]1346static int og_cmd_get_client_info(json_t *element,
1347                                  struct og_msg_params *params,
1348                                  char *buffer_reply)
1349{
1350        struct og_computer computer = {};
1351        json_t *value, *root;
1352        struct in_addr addr;
1353        struct og_dbi *dbi;
1354        const char *key;
1355        int err = 0;
1356
1357        struct og_buffer og_buffer = {
1358                .data = buffer_reply
1359        };
1360
1361        json_object_foreach(element, key, value) {
1362                if (!strcmp(key, "client")) {
1363                        err = og_json_parse_clients(value, params);
1364                }
1365
1366                if (err < 0)
[e7e80cd]1367                        return err;
[af47a08]1368        }
1369
1370        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1371                return -1;
1372
1373        if (params->ips_array_len != 1)
1374                return -1;
1375
1376        if (inet_aton(params->ips_array[0], &addr) == 0)
1377                return -1;
1378
[fe1ce97]1379        dbi = og_dbi_open(&ogconfig.db);
[af47a08]1380        if (!dbi) {
1381                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
1382                       __func__, __LINE__);
1383                return -1;
1384        }
1385
1386        if (og_dbi_get_computer_info(dbi, &computer, addr)) {
1387                og_dbi_close(dbi);
1388                return -1;
1389        }
1390
1391        og_dbi_close(dbi);
1392
1393        root = json_object();
1394        if (!root)
1395                return -1;
1396
1397        json_object_set_new(root, "serial_number",
1398                            json_string(computer.serial_number));
1399        json_object_set_new(root, "hardware_id",
1400                            json_integer(computer.hardware_id));
1401        json_object_set_new(root, "netdriver", json_string(computer.netdriver));
1402        json_object_set_new(root, "maintenance", json_boolean(computer.name));
1403        json_object_set_new(root, "netiface", json_string(computer.netiface));
1404        json_object_set_new(root, "repo_id", json_integer(computer.repo_id));
1405        json_object_set_new(root, "livedir", json_string(computer.livedir));
1406        json_object_set_new(root, "netmask", json_string(computer.netmask));
1407        json_object_set_new(root, "center", json_integer(computer.center));
1408        json_object_set_new(root, "remote", json_boolean(computer.remote));
1409        json_object_set_new(root, "room", json_integer(computer.room));
1410        json_object_set_new(root, "name", json_string(computer.name));
1411        json_object_set_new(root, "boot", json_string(computer.boot));
1412        json_object_set_new(root, "mac", json_string(computer.mac));
1413        json_object_set_new(root, "id", json_integer(computer.id));
1414        json_object_set_new(root, "ip", json_string(computer.ip));
1415
[2c6cef7]1416        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
1417                json_decref(root);
1418                return -1;
1419        }
1420
[af47a08]1421        json_decref(root);
1422        return 0;
1423}
1424
[65a14e5]1425static int og_cmd_post_client_add(json_t *element,
1426                                  struct og_msg_params *params,
1427                                  char *buffer_reply)
1428{
1429        struct og_computer computer = {};
[f537daf]1430        const char *key, *msglog;
[65a14e5]1431        struct og_dbi *dbi;
1432        dbi_result result;
1433        json_t *value;
1434        int err = 0;
1435
1436        json_object_foreach(element, key, value) {
1437                if (!strcmp(key, "serial_number")) {
[f537daf]1438                        err = og_json_parse_string_copy(value,
1439                                                        computer.serial_number,
1440                                                        sizeof(computer.serial_number));
[65a14e5]1441                } else if (!strcmp(key, "hardware_id")) {
1442                        err = og_json_parse_uint(value, &computer.hardware_id);
1443                } else if (!strcmp(key, "netdriver")) {
[f537daf]1444                        err = og_json_parse_string_copy(value,
1445                                                        computer.netdriver,
1446                                                        sizeof(computer.netdriver));
[65a14e5]1447                } else if (!strcmp(key, "maintenance")) {
1448                        err = og_json_parse_bool(value, &computer.maintenance);
1449                } else if (!strcmp(key, "netiface")) {
[f537daf]1450                        err = og_json_parse_string_copy(value,
1451                                                        computer.netiface,
1452                                                        sizeof(computer.netiface));
[65a14e5]1453                } else if (!strcmp(key, "repo_id")) {
1454                        err = og_json_parse_uint(value, &computer.repo_id);
1455                } else if (!strcmp(key, "livedir")) {
[f537daf]1456                        err = og_json_parse_string_copy(value,
1457                                                        computer.livedir,
1458                                                        sizeof(computer.livedir));
[65a14e5]1459                } else if (!strcmp(key, "netmask")) {
[f537daf]1460                        err = og_json_parse_string_copy(value,
1461                                                        computer.netmask,
1462                                                        sizeof(computer.netmask));
[65a14e5]1463                } else if (!strcmp(key, "remote")) {
1464                        err = og_json_parse_bool(value, &computer.remote);
1465                } else if (!strcmp(key, "room")) {
1466                        err = og_json_parse_uint(value, &computer.room);
1467                } else if (!strcmp(key, "name")) {
[f537daf]1468                        err = og_json_parse_string_copy(value,
1469                                                        computer.name,
1470                                                        sizeof(computer.name));
[65a14e5]1471                } else if (!strcmp(key, "boot")) {
[f537daf]1472                        err = og_json_parse_string_copy(value,
1473                                                        computer.boot,
1474                                                        sizeof(computer.boot));
[65a14e5]1475                } else if (!strcmp(key, "mac")) {
[f537daf]1476                        err = og_json_parse_string_copy(value,
1477                                                        computer.mac,
1478                                                        sizeof(computer.mac));
[65a14e5]1479                } else if (!strcmp(key, "ip")) {
[f537daf]1480                        err = og_json_parse_string_copy(value,
1481                                                        computer.ip,
1482                                                        sizeof(computer.ip));
[65a14e5]1483                }
1484
1485                if (err < 0)
[e7e80cd]1486                        return err;
[65a14e5]1487        }
1488
[fe1ce97]1489        dbi = og_dbi_open(&ogconfig.db);
[65a14e5]1490        if (!dbi) {
1491                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
1492                       __func__, __LINE__);
1493                return -1;
1494        }
1495
1496        result = dbi_conn_queryf(dbi->conn,
1497                                 "SELECT ip FROM ordenadores WHERE ip='%s'",
1498                                 computer.ip);
1499
1500        if (!result) {
1501                dbi_conn_error(dbi->conn, &msglog);
1502                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1503                       __func__, __LINE__, msglog);
1504                og_dbi_close(dbi);
1505                return -1;
1506        }
1507
1508        if (dbi_result_get_numrows(result) > 0) {
1509                syslog(LOG_ERR, "client with the same IP already exists: %s\n",
1510                       computer.ip);
1511                dbi_result_free(result);
1512                og_dbi_close(dbi);
1513                return -1;
1514        }
1515        dbi_result_free(result);
1516
1517        result = dbi_conn_queryf(dbi->conn,
1518                                 "INSERT INTO ordenadores("
1519                                 "  nombreordenador,"
1520                                 "  numserie,"
1521                                 "  ip,"
1522                                 "  mac,"
1523                                 "  idaula,"
1524                                 "  idperfilhard,"
1525                                 "  idrepositorio,"
1526                                 "  mascara,"
1527                                 "  arranque,"
1528                                 "  netiface,"
1529                                 "  netdriver,"
1530                                 "  oglivedir,"
1531                                 "  inremotepc,"
1532                                 "  maintenance"
1533                                 ") VALUES ('%s', '%s', '%s', '%s', %u, %u,"
1534                                 "           %u, '%s', '%s', '%s', '%s',"
1535                                 "          '%s', %u, %u)",
1536                                 computer.name, computer.serial_number,
1537                                 computer.ip, computer.mac, computer.room,
1538                                 computer.hardware_id, computer.repo_id,
1539                                 computer.netmask, computer.boot,
1540                                 computer.netiface, computer.netdriver,
1541                                 computer.livedir, computer.remote,
1542                                 computer.maintenance);
1543
1544        if (!result) {
1545                dbi_conn_error(dbi->conn, &msglog);
1546                syslog(LOG_ERR, "failed to add client to database (%s:%d) %s\n",
1547                       __func__, __LINE__, msglog);
1548                og_dbi_close(dbi);
1549                return -1;
1550        }
1551
1552        dbi_result_free(result);
1553        og_dbi_close(dbi);
1554        return 0;
1555}
1556
[24c8b94]1557static int og_cmd_post_client_delete(json_t *element,
1558                                     struct og_msg_params *params)
1559{
1560        const char *key, *msglog;
1561        struct og_dbi *dbi;
1562        dbi_result result;
1563        unsigned int i;
1564        json_t *value;
1565        int err = 0;
1566
1567        json_object_foreach(element, key, value) {
1568                if (!strcmp(key, "clients"))
1569                        err = og_json_parse_clients(value, params);
1570
1571                if (err < 0)
[e7e80cd]1572                        return err;
[24c8b94]1573        }
1574
1575        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1576                return -1;
1577
1578        dbi = og_dbi_open(&ogconfig.db);
1579        if (!dbi) {
1580                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
1581                       __func__, __LINE__);
1582                return -1;
1583        }
1584
1585        for (i = 0; i < params->ips_array_len; i++) {
1586                result = dbi_conn_queryf(dbi->conn,
1587                                         "DELETE FROM ordenadores WHERE ip='%s'",
1588                                         params->ips_array[i]);
1589
1590                if (!result) {
1591                        dbi_conn_error(dbi->conn, &msglog);
1592                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1593                               __func__, __LINE__, msglog);
1594                        og_dbi_close(dbi);
1595                        return -1;
1596                }
1597
1598                dbi_result_free(result);
1599        }
1600
1601        og_dbi_close(dbi);
1602        return 0;
1603}
1604
[04ca20e]1605static int og_cmd_stop(json_t *element, struct og_msg_params *params)
1606{
1607        const char *key;
1608        json_t *value;
1609        int err = 0;
1610
1611        if (json_typeof(element) != JSON_OBJECT)
1612                return -1;
1613
1614        json_object_foreach(element, key, value) {
1615                if (!strcmp(key, "clients"))
1616                        err = og_json_parse_clients(value, params);
1617
1618                if (err < 0)
[e7e80cd]1619                        return err;
[04ca20e]1620        }
1621
1622        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1623                return -1;
1624
1625        return og_send_request(OG_METHOD_POST, OG_CMD_STOP, params, NULL);
1626}
1627
1628static int og_cmd_hardware(json_t *element, struct og_msg_params *params)
1629{
1630        const char *key;
1631        json_t *value;
1632        int err = 0;
1633
1634        if (json_typeof(element) != JSON_OBJECT)
1635                return -1;
1636
1637        json_object_foreach(element, key, value) {
1638                if (!strcmp(key, "clients"))
1639                        err = og_json_parse_clients(value, params);
1640
1641                if (err < 0)
[e7e80cd]1642                        return err;
[04ca20e]1643        }
1644
1645        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
1646                return -1;
1647
1648        return og_send_request(OG_METHOD_GET, OG_CMD_HARDWARE, params, NULL);
1649}
1650
[a8eccba]1651static int og_cmd_get_hardware(json_t *element, struct og_msg_params *params,
1652                               char *buffer_reply)
1653{
1654        const char *key, *msglog, *hw_item, *hw_type;
1655        json_t *value, *root, *array, *item;
1656        struct og_dbi *dbi;
1657        dbi_result result;
1658        int err = 0;
1659
1660        struct og_buffer og_buffer = {
1661                .data = buffer_reply
1662        };
1663
1664        json_object_foreach(element, key, value) {
[2958d23]1665                if (!strcmp(key, "client"))
1666                        err = og_json_parse_clients(value, params);
[a8eccba]1667
1668                if (err < 0)
1669                        return err;
1670        }
1671
[2958d23]1672        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
[a8eccba]1673                return -1;
1674
[fe1ce97]1675        dbi = og_dbi_open(&ogconfig.db);
[a8eccba]1676        if (!dbi) {
1677                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
1678                       __func__, __LINE__);
1679                return -1;
1680        }
1681
1682        result = dbi_conn_queryf(dbi->conn,
1683                                 "SELECT hardwares.descripcion AS item, "
1684                                 "       tipohardwares.descripcion AS type "
1685                                 "FROM hardwares "
1686                                 "INNER JOIN perfileshard_hardwares "
1687                                 "    ON hardwares.idhardware = perfileshard_hardwares.idhardware "
1688                                 "INNER JOIN ordenadores "
1689                                 "    ON perfileshard_hardwares.idperfilhard = ordenadores.idperfilhard "
1690                                 "INNER JOIN tipohardwares "
1691                                 "    ON hardwares.idtipohardware = tipohardwares.idtipohardware "
[2958d23]1692                                 "WHERE ordenadores.ip = '%s'",
1693                                 params->ips_array[0]);
[a8eccba]1694        if (!result) {
1695                dbi_conn_error(dbi->conn, &msglog);
1696                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1697                       __func__, __LINE__, msglog);
1698                og_dbi_close(dbi);
1699                return -1;
1700        }
1701
1702        array = json_array();
1703        if (!array) {
1704                dbi_result_free(result);
1705                og_dbi_close(dbi);
1706                return -1;
1707        }
1708
1709        while (dbi_result_next_row(result)) {
1710                item = json_object();
1711                if (!item) {
1712                        dbi_result_free(result);
1713                        og_dbi_close(dbi);
1714                        json_decref(array);
1715                        return -1;
1716                }
1717
1718                hw_item = dbi_result_get_string(result, "item");
1719                hw_type = dbi_result_get_string(result, "type");
1720
1721                json_object_set_new(item, "type", json_string(hw_type));
1722                json_object_set_new(item, "description", json_string(hw_item));
1723                json_array_append_new(array, item);
1724        }
1725
1726        dbi_result_free(result);
1727        og_dbi_close(dbi);
1728
1729        root = json_object();
1730        if (!root){
1731                json_decref(array);
1732                return -1;
1733        }
1734
1735        json_object_set_new(root, "hardware", array);
1736
[2c6cef7]1737        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
1738                json_decref(root);
1739                return -1;
1740        }
1741
[a8eccba]1742        json_decref(root);
1743        return 0;
1744}
1745
[04ca20e]1746static int og_cmd_software(json_t *element, struct og_msg_params *params)
1747{
1748        json_t *clients, *value;
1749        const char *key;
1750        int err = 0;
1751
1752        if (json_typeof(element) != JSON_OBJECT)
1753                return -1;
1754
1755        json_object_foreach(element, key, value) {
1756                if (!strcmp(key, "clients"))
1757                        err = og_json_parse_clients(value, params);
1758                else if (!strcmp(key, "disk")) {
1759                        err = og_json_parse_string(value, &params->disk);
1760                        params->flags |= OG_REST_PARAM_DISK;
1761                }
1762                else if (!strcmp(key, "partition")) {
1763                        err = og_json_parse_string(value, &params->partition);
1764                        params->flags |= OG_REST_PARAM_PARTITION;
1765                }
1766
1767                if (err < 0)
[e7e80cd]1768                        return err;
[04ca20e]1769        }
1770
1771        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
1772                                            OG_REST_PARAM_DISK |
1773                                            OG_REST_PARAM_PARTITION))
1774                return -1;
1775
1776        clients = json_copy(element);
1777        json_object_del(clients, "clients");
1778
[8d91456]1779        return og_send_request(OG_METHOD_GET, OG_CMD_SOFTWARE, params, clients);
[04ca20e]1780}
1781
[25c1c16]1782static int og_cmd_get_software(json_t *element, struct og_msg_params *params,
1783                               char *buffer_reply)
1784{
1785        json_t *value, *software, *root;
1786        const char *key, *msglog, *name;
1787        uint64_t disk, partition;
1788        uint64_t flags = 0;
1789        struct og_dbi *dbi;
1790        dbi_result result;
1791        int err = 0;
1792
1793        struct og_buffer og_buffer = {
1794                .data = buffer_reply
1795        };
1796
1797        if (json_typeof(element) != JSON_OBJECT)
1798                return -1;
1799
1800        json_object_foreach(element, key, value) {
1801                if (!strcmp(key, "client")) {
1802                        err = og_json_parse_clients(value, params);
1803                } else if (!strcmp(key, "disk")) {
1804                        err = og_json_parse_uint64(value, &disk);
1805                        flags |= OG_REST_PARAM_DISK;
1806                } else if (!strcmp(key, "partition")) {
1807                        err = og_json_parse_uint64(value, &partition);
1808                        flags |= OG_REST_PARAM_PARTITION;
1809                }
1810
1811                if (err < 0)
[e7e80cd]1812                        return err;
[25c1c16]1813        }
1814
1815        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR) ||
1816            !og_flags_validate(flags, OG_REST_PARAM_DISK |
1817                                      OG_REST_PARAM_PARTITION))
1818                return -1;
1819
1820        dbi = og_dbi_open(&ogconfig.db);
1821        if (!dbi) {
1822                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
1823                       __func__, __LINE__);
1824                return -1;
1825        }
1826
1827        result = dbi_conn_queryf(dbi->conn,
1828                                 "SELECT s.descripcion "
1829                                 "FROM softwares s "
1830                                 "INNER JOIN perfilessoft_softwares pss "
1831                                 "ON s.idsoftware = pss.idsoftware "
1832                                 "INNER JOIN ordenadores_particiones op "
1833                                 "ON pss.idperfilsoft = op.idperfilsoft "
1834                                 "INNER JOIN ordenadores o "
1835                                 "ON o.idordenador = op.idordenador "
1836                                 "WHERE o.ip='%s' AND "
1837                                 "      op.numdisk=%lu AND "
1838                                 "      op.numpar=%lu",
1839                                 params->ips_array[0], disk, partition);
1840        if (!result) {
1841                dbi_conn_error(dbi->conn, &msglog);
1842                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1843                       __func__, __LINE__, msglog);
1844                return -1;
1845        }
1846        software = json_array();
1847        if (!software) {
1848                dbi_result_free(result);
1849                og_dbi_close(dbi);
1850                return -1;
1851        }
1852
1853        while (dbi_result_next_row(result)) {
1854                name = dbi_result_get_string(result, "descripcion");
1855                json_array_append_new(software, json_string(name));
1856        }
1857
1858        dbi_result_free(result);
1859        og_dbi_close(dbi);
1860
1861        root = json_object();
1862        if (!root) {
1863                json_decref(software);
1864                return -1;
1865        }
1866        json_object_set_new(root, "software", software);
1867
[2c6cef7]1868        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
1869                json_decref(root);
1870                return -1;
1871        }
1872
[25c1c16]1873        json_decref(root);
1874        return 0;
1875}
1876
[403e7c3]1877#define OG_IMAGE_TYPE_MAXLEN    4
1878
1879static int og_get_image_stats(const char *name,
1880                              struct stat *image_stats)
1881{
[3cea4bb]1882        const char *dir = ogconfig.repo.dir;
[403e7c3]1883        char filename[PATH_MAX + 1];
1884
[d8b78bb]1885        snprintf(filename, sizeof(filename), "%s/%s.img", dir, name);
[403e7c3]1886        if (stat(filename, image_stats) < 0) {
1887                syslog(LOG_ERR, "%s image does not exists", name);
1888                return -1;
1889        }
1890        return 0;
1891}
1892
1893static json_t *og_json_disk_alloc()
1894{
[3cea4bb]1895        const char *dir = ogconfig.repo.dir;
[403e7c3]1896        struct statvfs buffer;
1897        json_t *disk_json;
1898        int ret;
1899
1900        ret = statvfs(dir, &buffer);
1901        if (ret)
1902                return NULL;
1903
1904        disk_json = json_object();
1905        if (!disk_json)
1906                return NULL;
1907
1908        json_object_set_new(disk_json, "total",
1909                            json_integer(buffer.f_blocks * buffer.f_frsize));
1910        json_object_set_new(disk_json, "free",
1911                            json_integer(buffer.f_bfree * buffer.f_frsize));
1912
1913        return disk_json;
1914}
1915
1916#define OG_PERMS_IRWX (S_IRWXU | S_IRWXG | S_IRWXO)
1917#define OG_PERMS_MAXLEN 4
1918
1919static json_t *og_json_image_alloc(struct og_image *image)
1920{
1921        char perms_string[OG_PERMS_MAXLEN];
1922        json_t *image_json;
1923        char *modified;
1924        uint16_t perms;
1925
1926        image_json = json_object();
1927        if (!image_json)
1928                return NULL;
1929
1930        perms = image->image_stats.st_mode & OG_PERMS_IRWX;
1931        snprintf(perms_string, sizeof(perms_string), "%o", perms);
1932
1933        modified = ctime(&image->image_stats.st_mtime);
1934        modified[strlen(modified) - 1] = '\0';
1935
[d8b78bb]1936        json_object_set_new(image_json, "name",
1937                            json_string(image->name));
[403e7c3]1938        json_object_set_new(image_json, "datasize",
1939                            json_integer(image->datasize));
1940        json_object_set_new(image_json, "size",
1941                            json_integer(image->image_stats.st_size));
1942        json_object_set_new(image_json, "modified",
1943                            json_string(modified));
1944        json_object_set_new(image_json, "permissions",
1945                            json_string(perms_string));
[d8b78bb]1946        json_object_set_new(image_json, "software_id",
1947                            json_integer(image->software_id));
1948        json_object_set_new(image_json, "type",
1949                            json_integer(image->type));
1950        json_object_set_new(image_json, "id",
1951                            json_integer(image->id));
[403e7c3]1952
1953        return image_json;
1954}
1955
1956static int og_cmd_images(char *buffer_reply)
1957{
1958        json_t *root, *images, *image_json, *disk_json;
1959        struct og_buffer og_buffer = {
1960                .data = buffer_reply
1961        };
1962        struct og_image image;
1963        struct og_dbi *dbi;
1964        dbi_result result;
1965
1966        root = json_object();
1967        if (!root)
1968                return -1;
1969
1970        images = json_array();
1971        if (!images) {
1972                json_decref(root);
1973                return -1;
1974        }
1975
1976        json_object_set_new(root, "images", images);
1977
[fe1ce97]1978        dbi = og_dbi_open(&ogconfig.db);
[403e7c3]1979        if (!dbi) {
1980                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
1981                       __func__, __LINE__);
1982                json_decref(root);
1983                return -1;
1984        }
1985
1986        result = dbi_conn_queryf(dbi->conn,
1987                                 "SELECT i.nombreca, o.nombreordenador, "
1988                                 "       i.clonator, i.compressor, "
[d8b78bb]1989                                 "       i.filesystem, i.datasize, "
1990                                 "       i.idperfilsoft, i.tipo, "
1991                                 "       i.idimagen "
[403e7c3]1992                                 "FROM imagenes i "
1993                                 "LEFT JOIN ordenadores o "
1994                                 "ON i.idordenador = o.idordenador");
1995
1996        while (dbi_result_next_row(result)) {
1997                image = (struct og_image){0};
1998                image.datasize = dbi_result_get_ulonglong(result, "datasize");
[d8b78bb]1999                image.software_id = dbi_result_get_ulonglong(result, "idperfilsoft");
2000                image.type = dbi_result_get_ulonglong(result, "tipo");
2001                image.id = dbi_result_get_ulonglong(result, "idimagen");
2002                snprintf(image.name, sizeof(image.name), "%s",
2003                         dbi_result_get_string(result, "nombreca"));
[403e7c3]2004
[d8b78bb]2005                if (og_get_image_stats(image.name, &image.image_stats)) {
[403e7c3]2006                        continue;
2007                }
2008
2009                image_json = og_json_image_alloc(&image);
2010                if (!image_json) {
2011                        dbi_result_free(result);
2012                        og_dbi_close(dbi);
2013                        json_decref(root);
2014                        return -1;
2015                }
2016
[76e6375]2017                json_array_append_new(images, image_json);
[403e7c3]2018        }
2019
2020        dbi_result_free(result);
2021        og_dbi_close(dbi);
2022
2023        disk_json = og_json_disk_alloc();
2024        if (!disk_json) {
2025                syslog(LOG_ERR, "cannot allocate disk json");
2026                json_decref(root);
2027                return -1;
2028        }
2029
2030        json_object_set_new(root, "disk", disk_json);
2031
[2c6cef7]2032        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
2033                json_decref(root);
2034                return -1;
2035        }
2036
[403e7c3]2037        json_decref(root);
2038
2039        return 0;
2040}
2041
[04ca20e]2042static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
2043{
[d2f20d0]2044        char new_image_id[OG_DB_INT_MAXLEN + 1];
2045        struct og_image image = {};
[04ca20e]2046        json_t *value, *clients;
[d2f20d0]2047        struct og_dbi *dbi;
[04ca20e]2048        const char *key;
2049        int err = 0;
2050
2051        if (json_typeof(element) != JSON_OBJECT)
2052                return -1;
2053
2054        json_object_foreach(element, key, value) {
2055                if (!strcmp(key, "disk")) {
2056                        err = og_json_parse_string(value, &params->disk);
2057                        params->flags |= OG_REST_PARAM_DISK;
2058                } else if (!strcmp(key, "partition")) {
2059                        err = og_json_parse_string(value, &params->partition);
2060                        params->flags |= OG_REST_PARAM_PARTITION;
2061                } else if (!strcmp(key, "name")) {
2062                        err = og_json_parse_string(value, &params->name);
2063                        params->flags |= OG_REST_PARAM_NAME;
2064                } else if (!strcmp(key, "repository")) {
2065                        err = og_json_parse_string(value, &params->repository);
2066                        params->flags |= OG_REST_PARAM_REPO;
2067                } else if (!strcmp(key, "clients")) {
2068                        err = og_json_parse_clients(value, params);
2069                } else if (!strcmp(key, "id")) {
2070                        err = og_json_parse_string(value, &params->id);
2071                        params->flags |= OG_REST_PARAM_ID;
2072                } else if (!strcmp(key, "code")) {
2073                        err = og_json_parse_string(value, &params->code);
2074                        params->flags |= OG_REST_PARAM_CODE;
[d2f20d0]2075                } else if (!strcmp(key, "description")) {
2076                        err = og_json_parse_string_copy(value,
2077                                                        image.description,
2078                                                        sizeof(image.description));
2079                } else if (!strcmp(key, "group_id")) {
2080                        err = og_json_parse_uint64(value, &image.group_id);
2081                } else if (!strcmp(key, "center_id")) {
2082                        err = og_json_parse_uint64(value, &image.center_id);
[04ca20e]2083                }
2084
2085                if (err < 0)
[e7e80cd]2086                        return err;
[04ca20e]2087        }
2088
2089        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
2090                                            OG_REST_PARAM_DISK |
2091                                            OG_REST_PARAM_PARTITION |
2092                                            OG_REST_PARAM_CODE |
2093                                            OG_REST_PARAM_ID |
2094                                            OG_REST_PARAM_NAME |
2095                                            OG_REST_PARAM_REPO))
2096                return -1;
2097
[d2f20d0]2098        /* If there is a description, this means the image is not in the DB. */
2099        if (image.description[0]) {
2100                snprintf(image.name, sizeof(image.name), "%s", params->name);
2101
2102                dbi = og_dbi_open(&ogconfig.db);
2103                if (!dbi) {
2104                        syslog(LOG_ERR,
2105                               "cannot open connection database (%s:%d)\n",
2106                               __func__, __LINE__);
2107                        return -1;
2108                }
2109
2110                err = og_dbi_add_image(dbi, &image);
2111
2112                og_dbi_close(dbi);
2113                if (err < 0)
2114                        return err;
2115
2116                snprintf(new_image_id, sizeof(new_image_id), "%u", err);
2117                params->id = new_image_id;
2118        }
2119
[04ca20e]2120        clients = json_copy(element);
2121        json_object_del(clients, "clients");
2122
2123        return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_CREATE, params,
2124                               clients);
2125}
2126
2127static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
2128{
2129        json_t *clients, *value;
2130        const char *key;
2131        int err = 0;
2132
2133        if (json_typeof(element) != JSON_OBJECT)
2134                return -1;
2135
2136        json_object_foreach(element, key, value) {
2137                if (!strcmp(key, "disk")) {
2138                        err = og_json_parse_string(value, &params->disk);
2139                        params->flags |= OG_REST_PARAM_DISK;
2140                } else if (!strcmp(key, "partition")) {
2141                        err = og_json_parse_string(value, &params->partition);
2142                        params->flags |= OG_REST_PARAM_PARTITION;
2143                } else if (!strcmp(key, "name")) {
2144                        err = og_json_parse_string(value, &params->name);
2145                        params->flags |= OG_REST_PARAM_NAME;
2146                } else if (!strcmp(key, "repository")) {
2147                        err = og_json_parse_string(value, &params->repository);
2148                        params->flags |= OG_REST_PARAM_REPO;
2149                } else if (!strcmp(key, "clients")) {
2150                        err = og_json_parse_clients(value, params);
2151                } else if (!strcmp(key, "type")) {
2152                        err = og_json_parse_string(value, &params->type);
2153                        params->flags |= OG_REST_PARAM_TYPE;
2154                } else if (!strcmp(key, "profile")) {
2155                        err = og_json_parse_string(value, &params->profile);
2156                        params->flags |= OG_REST_PARAM_PROFILE;
2157                } else if (!strcmp(key, "id")) {
2158                        err = og_json_parse_string(value, &params->id);
2159                        params->flags |= OG_REST_PARAM_ID;
2160                }
2161
2162                if (err < 0)
[e7e80cd]2163                        return err;
[04ca20e]2164        }
2165
2166        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
2167                                            OG_REST_PARAM_DISK |
2168                                            OG_REST_PARAM_PARTITION |
2169                                            OG_REST_PARAM_NAME |
2170                                            OG_REST_PARAM_REPO |
2171                                            OG_REST_PARAM_TYPE |
2172                                            OG_REST_PARAM_PROFILE |
2173                                            OG_REST_PARAM_ID))
2174                return -1;
2175
2176        clients = json_copy(element);
2177        json_object_del(clients, "clients");
2178
2179        return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, params,
2180                               clients);
2181}
2182
2183static int og_cmd_setup(json_t *element, struct og_msg_params *params)
2184{
2185        json_t *value, *clients;
2186        const char *key;
2187        int err = 0;
2188
2189        if (json_typeof(element) != JSON_OBJECT)
2190                return -1;
2191
2192        json_object_foreach(element, key, value) {
2193                if (!strcmp(key, "clients")) {
2194                        err = og_json_parse_clients(value, params);
[0dd3edd]2195                } else if (!strcmp(key, "type")) {
2196                        err = og_json_parse_string(value, &params->type);
2197                        params->flags |= OG_REST_PARAM_TYPE;
[04ca20e]2198                } else if (!strcmp(key, "disk")) {
2199                        err = og_json_parse_string(value, &params->disk);
2200                        params->flags |= OG_REST_PARAM_DISK;
2201                } else if (!strcmp(key, "cache")) {
2202                        err = og_json_parse_string(value, &params->cache);
2203                        params->flags |= OG_REST_PARAM_CACHE;
2204                } else if (!strcmp(key, "cache_size")) {
2205                        err = og_json_parse_string(value, &params->cache_size);
2206                        params->flags |= OG_REST_PARAM_CACHE_SIZE;
2207                } else if (!strcmp(key, "partition_setup")) {
2208                        err = og_json_parse_partition_setup(value, params);
2209                }
2210
2211                if (err < 0)
[e7e80cd]2212                        return err;
[04ca20e]2213        }
2214
2215        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
[0dd3edd]2216                                            OG_REST_PARAM_TYPE |
[04ca20e]2217                                            OG_REST_PARAM_DISK |
2218                                            OG_REST_PARAM_CACHE |
2219                                            OG_REST_PARAM_CACHE_SIZE |
2220                                            OG_REST_PARAM_PART_0 |
2221                                            OG_REST_PARAM_PART_1 |
2222                                            OG_REST_PARAM_PART_2 |
2223                                            OG_REST_PARAM_PART_3))
2224                return -1;
2225
2226        clients = json_copy(element);
2227        json_object_del(clients, "clients");
2228
2229        return og_send_request(OG_METHOD_POST, OG_CMD_SETUP, params, clients);
2230}
2231
2232static int og_cmd_run_schedule(json_t *element, struct og_msg_params *params)
2233{
2234        const char *key;
2235        json_t *value;
2236        int err = 0;
2237
2238        json_object_foreach(element, key, value) {
2239                if (!strcmp(key, "clients"))
2240                        err = og_json_parse_clients(value, params);
2241
2242                if (err < 0)
[e7e80cd]2243                        return err;
[04ca20e]2244        }
2245
2246        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
2247                return -1;
2248
2249        return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params,
2250                               NULL);
2251}
2252
2253static LIST_HEAD(cmd_list);
2254
2255const struct og_cmd *og_cmd_find(const char *client_ip)
2256{
2257        struct og_cmd *cmd, *next;
2258
2259        list_for_each_entry_safe(cmd, next, &cmd_list, list) {
2260                if (strcmp(cmd->ip, client_ip))
2261                        continue;
2262
2263                list_del(&cmd->list);
2264                return cmd;
2265        }
2266
2267        return NULL;
2268}
2269
2270void og_cmd_free(const struct og_cmd *cmd)
2271{
2272        struct og_msg_params *params = (struct og_msg_params *)&cmd->params;
2273        int i;
2274
2275        for (i = 0; i < params->ips_array_len; i++) {
[ed0d86b]2276                free((void *)params->netmask_array[i]);
[04ca20e]2277                free((void *)params->ips_array[i]);
2278                free((void *)params->mac_array[i]);
2279        }
2280        free((void *)params->wol_type);
2281
2282        if (cmd->json)
2283                json_decref(cmd->json);
2284
2285        free((void *)cmd->ip);
2286        free((void *)cmd->mac);
2287        free((void *)cmd);
2288}
2289
2290static void og_cmd_init(struct og_cmd *cmd, enum og_rest_method method,
2291                        enum og_cmd_type type, json_t *root)
2292{
2293        cmd->type = type;
2294        cmd->method = method;
2295        cmd->params.ips_array[0] = strdup(cmd->ip);
2296        cmd->params.ips_array_len = 1;
2297        cmd->json = root;
2298}
2299
2300static int og_cmd_legacy_wol(const char *input, struct og_cmd *cmd)
2301{
2302        char wol_type[2] = {};
[ed0d86b]2303        const char *msglog;
2304        struct og_dbi *dbi;
2305        dbi_result result;
[04ca20e]2306
2307        if (sscanf(input, "mar=%s", wol_type) != 1) {
2308                syslog(LOG_ERR, "malformed database legacy input\n");
2309                return -1;
2310        }
2311
[ed0d86b]2312        dbi = og_dbi_open(&ogconfig.db);
2313        if (!dbi) {
2314                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2315                       __func__, __LINE__);
2316                return -1;
2317        }
2318
2319        result = dbi_conn_queryf(dbi->conn,
[e6c2c26]2320                                 "SELECT aulas.netmask "
2321                                 "FROM   ordenadores "
2322                                 "INNER JOIN aulas "
2323                                         "ON ordenadores.idaula = aulas.idaula "
2324                                 "WHERE  ordenadores.ip = '%s'",
2325                                 cmd->ip);
[ed0d86b]2326        if (!result) {
2327                dbi_conn_error(dbi->conn, &msglog);
2328                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2329                       __func__, __LINE__, msglog);
2330                og_dbi_close(dbi);
2331                return -1;
2332        }
2333        dbi_result_next_row(result);
2334
[04ca20e]2335        og_cmd_init(cmd, OG_METHOD_NO_HTTP, OG_CMD_WOL, NULL);
[ed0d86b]2336        cmd->params.netmask_array[0] = dbi_result_get_string_copy(result,
[e6c2c26]2337                                                                  "netmask");
[04ca20e]2338        cmd->params.mac_array[0] = strdup(cmd->mac);
2339        cmd->params.wol_type = strdup(wol_type);
2340
[ed0d86b]2341        dbi_result_free(result);
2342        og_dbi_close(dbi);
2343
[04ca20e]2344        return 0;
2345}
2346
2347static int og_cmd_legacy_shell_run(const char *input, struct og_cmd *cmd)
2348{
2349        json_t *root, *script, *echo;
2350
2351        script = json_string(input + 4);
2352        echo = json_boolean(false);
2353
2354        root = json_object();
2355        if (!root)
2356                return -1;
2357        json_object_set_new(root, "run", script);
2358        json_object_set_new(root, "echo", echo);
2359
2360        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SHELL_RUN, root);
2361
2362        return 0;
2363}
2364
2365static int og_cmd_legacy_session(const char *input, struct og_cmd *cmd)
2366{
2367        char part_str[OG_DB_SMALLINT_MAXLEN + 1];
2368        char disk_str[OG_DB_SMALLINT_MAXLEN + 1];
2369        json_t *root, *disk, *partition;
2370
2371        if (sscanf(input, "dsk=%s\rpar=%s\r", disk_str, part_str) != 2)
2372                return -1;
2373        partition = json_string(part_str);
2374        disk = json_string(disk_str);
2375
2376        root = json_object();
2377        if (!root)
2378                return -1;
2379        json_object_set_new(root, "partition", partition);
2380        json_object_set_new(root, "disk", disk);
2381
2382        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SESSION, root);
2383
2384        return 0;
2385}
2386
2387static int og_cmd_legacy_poweroff(const char *input, struct og_cmd *cmd)
2388{
2389        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_POWEROFF, NULL);
2390
2391        return 0;
2392}
2393
2394static int og_cmd_legacy_refresh(const char *input, struct og_cmd *cmd)
2395{
2396        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_REFRESH, NULL);
2397
2398        return 0;
2399}
2400
2401static int og_cmd_legacy_reboot(const char *input, struct og_cmd *cmd)
2402{
2403        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_REBOOT, NULL);
2404
2405        return 0;
2406}
2407
2408static int og_cmd_legacy_stop(const char *input, struct og_cmd *cmd)
2409{
2410        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_STOP, NULL);
2411
2412        return 0;
2413}
2414
2415static int og_cmd_legacy_hardware(const char *input, struct og_cmd *cmd)
2416{
2417        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_HARDWARE, NULL);
2418
2419        return 0;
2420}
2421
2422static int og_cmd_legacy_software(const char *input, struct og_cmd *cmd)
2423{
[6d628dc]2424        char part_str[OG_DB_SMALLINT_MAXLEN + 1];
2425        char disk_str[OG_DB_SMALLINT_MAXLEN + 1];
2426        json_t *root, *disk, *partition;
2427
2428        if (sscanf(input, "dsk=%s\rpar=%s\r", disk_str, part_str) != 2)
2429                return -1;
2430        partition = json_string(part_str);
2431        disk = json_string(disk_str);
2432
2433        root = json_object();
2434        if (!root)
2435                return -1;
2436        json_object_set_new(root, "partition", partition);
2437        json_object_set_new(root, "disk", disk);
2438
2439        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_SOFTWARE, root);
[04ca20e]2440
2441        return 0;
2442}
2443
2444static int og_cmd_legacy_image_create(const char *input, struct og_cmd *cmd)
2445{
2446        json_t *root, *disk, *partition, *code, *image_id, *name, *repo;
2447        struct og_image_legacy img = {};
2448
2449        if (sscanf(input, "dsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s\r",
2450                   img.disk, img.part, img.code, img.image_id, img.name,
2451                   img.repo) != 6)
2452                return -1;
2453        image_id = json_string(img.image_id);
2454        partition = json_string(img.part);
2455        code = json_string(img.code);
2456        name = json_string(img.name);
2457        repo = json_string(img.repo);
2458        disk = json_string(img.disk);
2459
2460        root = json_object();
2461        if (!root)
2462                return -1;
2463        json_object_set_new(root, "partition", partition);
2464        json_object_set_new(root, "repository", repo);
2465        json_object_set_new(root, "id", image_id);
2466        json_object_set_new(root, "code", code);
2467        json_object_set_new(root, "name", name);
2468        json_object_set_new(root, "disk", disk);
2469
2470        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_CREATE, root);
2471
2472        return 0;
2473}
2474
2475#define OG_DB_RESTORE_TYPE_MAXLEN       64
2476
2477static int og_cmd_legacy_image_restore(const char *input, struct og_cmd *cmd)
2478{
2479        json_t *root, *disk, *partition, *image_id, *name, *repo;
2480        char restore_type_str[OG_DB_RESTORE_TYPE_MAXLEN + 1] = {};
2481        char software_id_str[OG_DB_INT_MAXLEN + 1] = {};
2482        json_t *software_id, *restore_type;
2483        struct og_image_legacy img = {};
2484
2485        if (sscanf(input,
[0e4857a]2486                   "dsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
2487                   "ipr=%s\rifs=%s\rptc=%[^\r]\r",
[04ca20e]2488                   img.disk, img.part, img.image_id, img.name, img.repo,
2489                   software_id_str, restore_type_str) != 7)
2490                return -1;
2491
2492        restore_type = json_string(restore_type_str);
2493        software_id = json_string(software_id_str);
2494        image_id = json_string(img.image_id);
2495        partition = json_string(img.part);
2496        name = json_string(img.name);
2497        repo = json_string(img.repo);
2498        disk = json_string(img.disk);
2499
2500        root = json_object();
2501        if (!root)
2502                return -1;
2503        json_object_set_new(root, "profile", software_id);
2504        json_object_set_new(root, "partition", partition);
2505        json_object_set_new(root, "type", restore_type);
2506        json_object_set_new(root, "repository", repo);
2507        json_object_set_new(root, "id", image_id);
2508        json_object_set_new(root, "name", name);
2509        json_object_set_new(root, "disk", disk);
2510
2511        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, root);
2512
2513        return 0;
2514}
2515
[6a7a846]2516#define OG_PARTITION_TABLE_TYPE_MAXLEN 5
2517
[04ca20e]2518static int og_cmd_legacy_setup(const char *input, struct og_cmd *cmd)
2519{
2520        json_t *root, *disk, *cache, *cache_size, *partition_setup, *object;
[6a7a846]2521        char part_table_type_str[OG_PARTITION_TABLE_TYPE_MAXLEN + 1];
[04ca20e]2522        struct og_legacy_partition part_cfg[OG_PARTITION_MAX] = {};
[6a7a846]2523        json_t *part_table_type, *part, *code, *fs, *size, *format;
[04ca20e]2524        char cache_size_str [OG_DB_INT_MAXLEN + 1];
2525        char disk_str [OG_DB_SMALLINT_MAXLEN + 1];
2526        unsigned int partition_len = 0;
2527        const char *in_ptr;
2528        char cache_str[2];
2529
[6a7a846]2530        if (sscanf(input, "ttp=%s\rdsk=%s\rcfg=dis=%*[^*]*che=%[^*]*tch=%[^!]!",
2531                   part_table_type_str, disk_str, cache_str, cache_size_str) != 4)
[04ca20e]2532                return -1;
2533
2534        in_ptr = strstr(input, "!") + 1;
2535        while (strlen(in_ptr) > 0) {
2536                if(sscanf(in_ptr,
2537                          "par=%[^*]*cpt=%[^*]*sfi=%[^*]*tam=%[^*]*ope=%[^%%]%%",
2538                          part_cfg[partition_len].partition,
2539                          part_cfg[partition_len].code,
2540                          part_cfg[partition_len].filesystem,
2541                          part_cfg[partition_len].size,
2542                          part_cfg[partition_len].format) != 5)
2543                        return -1;
2544                in_ptr = strstr(in_ptr, "%") + 1;
2545                partition_len++;
2546        }
2547
2548        root = json_object();
2549        if (!root)
2550                return -1;
2551
[6a7a846]2552        part_table_type = json_string(part_table_type_str);
[04ca20e]2553        cache_size = json_string(cache_size_str);
2554        cache = json_string(cache_str);
2555        partition_setup = json_array();
2556        disk = json_string(disk_str);
2557
2558        for (unsigned int i = 0; i < partition_len; ++i) {
2559                object = json_object();
2560                if (!object) {
2561                        json_decref(root);
2562                        return -1;
2563                }
2564
2565                part = json_string(part_cfg[i].partition);
2566                fs = json_string(part_cfg[i].filesystem);
2567                format = json_string(part_cfg[i].format);
2568                code = json_string(part_cfg[i].code);
2569                size = json_string(part_cfg[i].size);
2570
2571                json_object_set_new(object, "partition", part);
2572                json_object_set_new(object, "filesystem", fs);
2573                json_object_set_new(object, "format", format);
2574                json_object_set_new(object, "code", code);
2575                json_object_set_new(object, "size", size);
2576
2577                json_array_append_new(partition_setup, object);
2578        }
2579
2580        json_object_set_new(root, "partition_setup", partition_setup);
2581        json_object_set_new(root, "cache_size", cache_size);
[6a7a846]2582        json_object_set_new(root, "type", part_table_type);
[04ca20e]2583        json_object_set_new(root, "cache", cache);
2584        json_object_set_new(root, "disk", disk);
2585
2586        og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SETUP, root);
2587
2588        return 0;
2589}
2590
2591static int og_cmd_legacy_run_schedule(const char *input, struct og_cmd *cmd)
2592{
2593        og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, NULL);
2594
2595        return 0;
2596}
2597
2598static int og_cmd_legacy(const char *input, struct og_cmd *cmd)
2599{
2600        char legacy_cmd[32] = {};
2601        int err = -1;
2602
2603        if (sscanf(input, "nfn=%31s\r", legacy_cmd) != 1) {
2604                syslog(LOG_ERR, "malformed database legacy input\n");
2605                return -1;
2606        }
2607        input = strchr(input, '\r') + 1;
2608
2609        if (!strcmp(legacy_cmd, "Arrancar")) {
2610                err = og_cmd_legacy_wol(input, cmd);
2611        } else if (!strcmp(legacy_cmd, "EjecutarScript")) {
2612                err = og_cmd_legacy_shell_run(input, cmd);
2613        } else if (!strcmp(legacy_cmd, "IniciarSesion")) {
2614                err = og_cmd_legacy_session(input, cmd);
2615        } else if (!strcmp(legacy_cmd, "Apagar")) {
2616                err = og_cmd_legacy_poweroff(input, cmd);
2617        } else if (!strcmp(legacy_cmd, "Actualizar")) {
2618                err = og_cmd_legacy_refresh(input, cmd);
2619        } else if (!strcmp(legacy_cmd, "Reiniciar")) {
2620                err = og_cmd_legacy_reboot(input, cmd);
2621        } else if (!strcmp(legacy_cmd, "Purgar")) {
2622                err = og_cmd_legacy_stop(input, cmd);
2623        } else if (!strcmp(legacy_cmd, "InventarioHardware")) {
2624                err = og_cmd_legacy_hardware(input, cmd);
2625        } else if (!strcmp(legacy_cmd, "InventarioSoftware")) {
2626                err = og_cmd_legacy_software(input, cmd);
2627        } else if (!strcmp(legacy_cmd, "CrearImagen")) {
2628                err = og_cmd_legacy_image_create(input, cmd);
2629        } else if (!strcmp(legacy_cmd, "RestaurarImagen")) {
2630                err = og_cmd_legacy_image_restore(input, cmd);
2631        } else if (!strcmp(legacy_cmd, "Configurar")) {
2632                err = og_cmd_legacy_setup(input, cmd);
2633        } else if (!strcmp(legacy_cmd, "EjecutaComandosPendientes") ||
2634                   !strcmp(legacy_cmd, "Actualizar")) {
2635                err = og_cmd_legacy_run_schedule(input, cmd);
2636        }
2637
2638        return err;
2639}
2640
2641static int og_dbi_add_action(const struct og_dbi *dbi, const struct og_task *task,
2642                             struct og_cmd *cmd)
2643{
2644        char start_date_string[24];
2645        struct tm *start_date;
2646        const char *msglog;
2647        dbi_result result;
2648        time_t now;
2649
2650        time(&now);
2651        start_date = localtime(&now);
2652
2653        sprintf(start_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu",
2654                start_date->tm_year + 1900, start_date->tm_mon + 1,
2655                start_date->tm_mday, start_date->tm_hour, start_date->tm_min,
2656                start_date->tm_sec);
2657        result = dbi_conn_queryf(dbi->conn,
2658                                "INSERT INTO acciones (idordenador, "
2659                                "tipoaccion, idtipoaccion, descriaccion, ip, "
2660                                "sesion, idcomando, parametros, fechahorareg, "
2661                                "estado, resultado, ambito, idambito, "
2662                                "restrambito, idprocedimiento, idcentro, "
2663                                "idprogramacion) "
2664                                "VALUES (%d, %d, %d, '%s', '%s', %d, %d, '%s', "
2665                                "'%s', %d, %d, %d, %d, '%s', %d, %d, %d)",
2666                                cmd->client_id, EJECUCION_TAREA, task->task_id,
2667                                "", cmd->ip, 0, task->command_id,
2668                                task->params, start_date_string,
2669                                ACCION_INICIADA, ACCION_SINRESULTADO,
2670                                task->type_scope, task->scope, "",
2671                                task->procedure_id, task->center_id,
2672                                task->schedule_id);
2673        if (!result) {
2674                dbi_conn_error(dbi->conn, &msglog);
2675                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2676                       __func__, __LINE__, msglog);
2677                return -1;
2678        }
2679        cmd->id = dbi_conn_sequence_last(dbi->conn, NULL);
2680        dbi_result_free(result);
2681
2682        return 0;
2683}
2684
2685static int og_queue_task_command(struct og_dbi *dbi, const struct og_task *task,
2686                                 char *query)
2687{
2688        struct og_cmd *cmd;
2689        const char *msglog;
2690        dbi_result result;
2691
2692        result = dbi_conn_queryf(dbi->conn, query);
2693        if (!result) {
2694                dbi_conn_error(dbi->conn, &msglog);
2695                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2696                       __func__, __LINE__, msglog);
2697                return -1;
2698        }
2699
2700        while (dbi_result_next_row(result)) {
2701                cmd = (struct og_cmd *)calloc(1, sizeof(struct og_cmd));
2702                if (!cmd) {
2703                        dbi_result_free(result);
2704                        return -1;
2705                }
2706
2707                cmd->client_id  = dbi_result_get_uint(result, "idordenador");
2708                cmd->ip         = strdup(dbi_result_get_string(result, "ip"));
2709                cmd->mac        = strdup(dbi_result_get_string(result, "mac"));
2710
2711                og_cmd_legacy(task->params, cmd);
2712
2713                if (task->procedure_id) {
2714                        if (og_dbi_add_action(dbi, task, cmd)) {
2715                                dbi_result_free(result);
2716                                return -1;
2717                        }
2718                } else {
2719                        cmd->id = task->task_id;
2720                }
2721
2722                list_add_tail(&cmd->list, &cmd_list);
2723        }
2724
2725        dbi_result_free(result);
2726
2727        return 0;
2728}
2729
2730static int og_queue_task_group_clients(struct og_dbi *dbi, struct og_task *task,
2731                                       char *query)
2732{
2733
2734        const char *msglog;
2735        dbi_result result;
2736
2737        result = dbi_conn_queryf(dbi->conn, query);
2738        if (!result) {
2739                dbi_conn_error(dbi->conn, &msglog);
2740                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2741                       __func__, __LINE__, msglog);
2742                return -1;
2743        }
2744
2745        while (dbi_result_next_row(result)) {
2746                uint32_t group_id = dbi_result_get_uint(result, "idgrupo");
2747
2748                sprintf(query, "SELECT idgrupo FROM gruposordenadores "
2749                                "WHERE grupoid=%d", group_id);
2750                if (og_queue_task_group_clients(dbi, task, query)) {
2751                        dbi_result_free(result);
2752                        return -1;
2753                }
2754
2755                sprintf(query,"SELECT ip, mac, idordenador FROM ordenadores "
2756                              "WHERE grupoid=%d", group_id);
2757                if (og_queue_task_command(dbi, task, query)) {
2758                        dbi_result_free(result);
2759                        return -1;
2760                }
2761
2762        }
2763
2764        dbi_result_free(result);
2765
2766        return 0;
2767}
2768
2769static int og_queue_task_group_classrooms(struct og_dbi *dbi,
2770                                          struct og_task *task, char *query)
2771{
2772
2773        const char *msglog;
2774        dbi_result result;
2775
2776        result = dbi_conn_queryf(dbi->conn, query);
2777        if (!result) {
2778                dbi_conn_error(dbi->conn, &msglog);
2779                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2780                       __func__, __LINE__, msglog);
2781                return -1;
2782        }
2783
2784        while (dbi_result_next_row(result)) {
2785                uint32_t group_id = dbi_result_get_uint(result, "idgrupo");
2786
2787                sprintf(query, "SELECT idgrupo FROM grupos "
2788                                "WHERE grupoid=%d AND tipo=%d", group_id, AMBITO_GRUPOSAULAS);
2789                if (og_queue_task_group_classrooms(dbi, task, query)) {
2790                        dbi_result_free(result);
2791                        return -1;
2792                }
2793
2794                sprintf(query,
2795                        "SELECT ip,mac,idordenador "
2796                        "FROM ordenadores INNER JOIN aulas "
2797                        "WHERE ordenadores.idaula=aulas.idaula "
2798                        "AND aulas.grupoid=%d",
2799                        group_id);
2800                if (og_queue_task_command(dbi, task, query)) {
2801                        dbi_result_free(result);
2802                        return -1;
2803                }
2804
2805        }
2806
2807        dbi_result_free(result);
2808
2809        return 0;
2810}
2811
2812static int og_queue_task_clients(struct og_dbi *dbi, struct og_task *task)
2813{
2814        char query[4096];
2815
2816        switch (task->type_scope) {
2817                case AMBITO_CENTROS:
2818                        sprintf(query,
2819                                "SELECT ip,mac,idordenador "
2820                                "FROM ordenadores INNER JOIN aulas "
2821                                "WHERE ordenadores.idaula=aulas.idaula "
2822                                "AND idcentro=%d",
2823                                task->scope);
2824                        return og_queue_task_command(dbi, task, query);
2825                case AMBITO_GRUPOSAULAS:
2826                        sprintf(query,
2827                                "SELECT idgrupo FROM grupos "
2828                                "WHERE idgrupo=%i AND tipo=%d",
2829                                task->scope, AMBITO_GRUPOSAULAS);
2830                        return og_queue_task_group_classrooms(dbi, task, query);
2831                case AMBITO_AULAS:
2832                        sprintf(query,
2833                                "SELECT ip,mac,idordenador FROM ordenadores "
2834                                "WHERE idaula=%d",
2835                                task->scope);
2836                        return og_queue_task_command(dbi, task, query);
2837                case AMBITO_GRUPOSORDENADORES:
2838                        sprintf(query,
2839                                "SELECT idgrupo FROM gruposordenadores "
2840                                "WHERE idgrupo = %d",
2841                                task->scope);
2842                        return og_queue_task_group_clients(dbi, task, query);
2843                case AMBITO_ORDENADORES:
2844                        sprintf(query,
2845                                "SELECT ip, mac, idordenador FROM ordenadores "
2846                                "WHERE idordenador = %d",
2847                                task->scope);
2848                        return og_queue_task_command(dbi, task, query);
2849        }
2850        return 0;
2851}
2852
2853int og_dbi_queue_procedure(struct og_dbi *dbi, struct og_task *task)
2854{
2855        uint32_t procedure_id;
2856        const char *msglog;
2857        dbi_result result;
2858
2859        result = dbi_conn_queryf(dbi->conn,
2860                        "SELECT parametros, procedimientoid, idcomando "
2861                        "FROM procedimientos_acciones "
2862                        "WHERE idprocedimiento=%d ORDER BY orden", task->procedure_id);
2863        if (!result) {
2864                dbi_conn_error(dbi->conn, &msglog);
2865                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2866                       __func__, __LINE__, msglog);
2867                return -1;
2868        }
2869
2870        while (dbi_result_next_row(result)) {
2871                procedure_id = dbi_result_get_uint(result, "procedimientoid");
2872                if (procedure_id > 0) {
2873                        task->procedure_id = procedure_id;
2874                        if (og_dbi_queue_procedure(dbi, task))
2875                                return -1;
2876                        continue;
2877                }
2878
[829f8d8]2879                task->params = dbi_result_get_string(result, "parametros");
[04ca20e]2880                task->command_id = dbi_result_get_uint(result, "idcomando");
2881                if (og_queue_task_clients(dbi, task))
2882                        return -1;
2883        }
2884
2885        dbi_result_free(result);
2886
2887        return 0;
2888}
2889
2890static int og_dbi_queue_task(struct og_dbi *dbi, uint32_t task_id,
2891                             uint32_t schedule_id)
2892{
2893        struct og_task task = {};
2894        uint32_t task_id_next;
2895        const char *msglog;
2896        dbi_result result;
2897
2898        task.schedule_id = schedule_id;
2899
2900        result = dbi_conn_queryf(dbi->conn,
2901                        "SELECT tareas_acciones.orden, "
2902                                "tareas_acciones.idprocedimiento, "
2903                                "tareas_acciones.tareaid, "
2904                                "tareas.idtarea, "
2905                                "tareas.idcentro, "
2906                                "tareas.ambito, "
2907                                "tareas.idambito, "
2908                                "tareas.restrambito "
2909                        " FROM tareas"
2910                                " INNER JOIN tareas_acciones ON tareas_acciones.idtarea=tareas.idtarea"
2911                        " WHERE tareas_acciones.idtarea=%u ORDER BY tareas_acciones.orden ASC", task_id);
2912        if (!result) {
2913                dbi_conn_error(dbi->conn, &msglog);
2914                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2915                       __func__, __LINE__, msglog);
2916                return -1;
2917        }
2918
2919        while (dbi_result_next_row(result)) {
2920                task_id_next = dbi_result_get_uint(result, "tareaid");
2921
2922                if (task_id_next > 0) {
2923                        if (og_dbi_queue_task(dbi, task_id_next, schedule_id))
2924                                return -1;
2925
2926                        continue;
2927                }
2928                task.task_id = dbi_result_get_uint(result, "idtarea");
2929                task.center_id = dbi_result_get_uint(result, "idcentro");
2930                task.procedure_id = dbi_result_get_uint(result, "idprocedimiento");
2931                task.type_scope = dbi_result_get_uint(result, "ambito");
2932                task.scope = dbi_result_get_uint(result, "idambito");
2933                task.filtered_scope = dbi_result_get_string(result, "restrambito");
2934
2935                og_dbi_queue_procedure(dbi, &task);
2936        }
2937
2938        dbi_result_free(result);
2939
2940        return 0;
2941}
2942
2943static int og_dbi_queue_command(struct og_dbi *dbi, uint32_t task_id,
2944                                uint32_t schedule_id)
2945{
2946        struct og_task task = {};
2947        const char *msglog;
2948        dbi_result result;
2949        char query[4096];
2950
2951        result = dbi_conn_queryf(dbi->conn,
2952                        "SELECT idaccion, idcentro, idordenador, parametros "
2953                        "FROM acciones "
2954                        "WHERE sesion = %u", task_id);
2955        if (!result) {
2956                dbi_conn_error(dbi->conn, &msglog);
2957                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2958                       __func__, __LINE__, msglog);
2959                return -1;
2960        }
2961
2962        while (dbi_result_next_row(result)) {
2963                task.task_id = dbi_result_get_uint(result, "idaccion");
2964                task.center_id = dbi_result_get_uint(result, "idcentro");
2965                task.scope = dbi_result_get_uint(result, "idordenador");
[829f8d8]2966                task.params = dbi_result_get_string(result, "parametros");
[04ca20e]2967
2968                sprintf(query,
2969                        "SELECT ip, mac, idordenador FROM ordenadores "
2970                        "WHERE idordenador = %d",
2971                        task.scope);
2972                if (og_queue_task_command(dbi, &task, query)) {
2973                        dbi_result_free(result);
2974                        return -1;
2975                }
2976        }
2977
2978        dbi_result_free(result);
2979
2980        return 0;
2981}
2982
2983int og_dbi_update_action(uint32_t id, bool success)
2984{
2985        char end_date_string[24];
2986        struct tm *end_date;
2987        const char *msglog;
2988        struct og_dbi *dbi;
2989        uint8_t status = 2;
2990        dbi_result result;
2991        time_t now;
2992
2993        if (!id)
2994                return 0;
2995
[fe1ce97]2996        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]2997        if (!dbi) {
2998                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
2999                       __func__, __LINE__);
3000                return -1;
3001        }
3002
3003        time(&now);
3004        end_date = localtime(&now);
3005
3006        sprintf(end_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu",
3007                end_date->tm_year + 1900, end_date->tm_mon + 1,
3008                end_date->tm_mday, end_date->tm_hour, end_date->tm_min,
3009                end_date->tm_sec);
3010        result = dbi_conn_queryf(dbi->conn,
3011                                 "UPDATE acciones SET fechahorafin='%s', "
3012                                 "estado=%d, resultado=%d WHERE idaccion=%d",
3013                                 end_date_string, ACCION_FINALIZADA,
3014                                 status - success, id);
3015
3016        if (!result) {
3017                dbi_conn_error(dbi->conn, &msglog);
3018                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3019                       __func__, __LINE__, msglog);
3020                og_dbi_close(dbi);
3021                return -1;
3022        }
3023        dbi_result_free(result);
3024        og_dbi_close(dbi);
3025
3026        return 0;
3027}
3028
3029void og_schedule_run(unsigned int task_id, unsigned int schedule_id,
3030                     enum og_schedule_type type)
3031{
3032        struct og_msg_params params = {};
3033        bool duplicated = false;
3034        struct og_cmd *cmd, *next;
3035        struct og_dbi *dbi;
3036        unsigned int i;
3037
[fe1ce97]3038        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3039        if (!dbi) {
3040                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3041                       __func__, __LINE__);
3042                return;
3043        }
3044
3045        switch (type) {
3046        case OG_SCHEDULE_TASK:
3047                og_dbi_queue_task(dbi, task_id, schedule_id);
3048                break;
3049        case OG_SCHEDULE_PROCEDURE:
3050        case OG_SCHEDULE_COMMAND:
3051                og_dbi_queue_command(dbi, task_id, schedule_id);
3052                break;
3053        }
3054        og_dbi_close(dbi);
3055
3056        list_for_each_entry(cmd, &cmd_list, list) {
3057                for (i = 0; i < params.ips_array_len; i++) {
3058                        if (!strncmp(cmd->ip, params.ips_array[i],
3059                                     OG_DB_IP_MAXLEN)) {
3060                                duplicated = true;
3061                                break;
3062                        }
3063                }
3064
3065                if (!duplicated)
[3b3405b]3066                        params.ips_array[params.ips_array_len++] = strdup(cmd->ip);
[04ca20e]3067                else
3068                        duplicated = false;
3069        }
3070
3071        list_for_each_entry_safe(cmd, next, &cmd_list, list) {
3072                if (cmd->type != OG_CMD_WOL)
3073                        continue;
3074
3075                if (Levanta((char **)cmd->params.ips_array,
3076                            (char **)cmd->params.mac_array,
[06af0c2]3077                            (char **)cmd->params.netmask_array,
[04ca20e]3078                            cmd->params.ips_array_len,
3079                            (char *)cmd->params.wol_type))
3080                        og_dbi_update_action(cmd->id, true);
3081
3082                list_del(&cmd->list);
3083                og_cmd_free(cmd);
3084        }
3085
3086        og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, &params, NULL);
[3b3405b]3087
3088        for (i = 0; i < params.ips_array_len; i++)
3089                free((void *)params.ips_array[i]);
[04ca20e]3090}
3091
3092static int og_cmd_task_post(json_t *element, struct og_msg_params *params)
3093{
3094        struct og_cmd *cmd;
3095        struct og_dbi *dbi;
3096        const char *key;
3097        json_t *value;
[e7e80cd]3098        int err = 0;
[04ca20e]3099
3100        if (json_typeof(element) != JSON_OBJECT)
3101                return -1;
3102
3103        json_object_foreach(element, key, value) {
3104                if (!strcmp(key, "task")) {
3105                        err = og_json_parse_string(value, &params->task_id);
3106                        params->flags |= OG_REST_PARAM_TASK;
3107                }
3108
3109                if (err < 0)
[e7e80cd]3110                        return err;
[04ca20e]3111        }
3112
3113        if (!og_msg_params_validate(params, OG_REST_PARAM_TASK))
3114                return -1;
3115
[fe1ce97]3116        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3117        if (!dbi) {
3118                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3119                           __func__, __LINE__);
3120                return -1;
3121        }
3122
3123        og_schedule_run(atoi(params->task_id), 0, OG_SCHEDULE_TASK);
3124        og_dbi_close(dbi);
3125
3126        list_for_each_entry(cmd, &cmd_list, list)
3127                params->ips_array[params->ips_array_len++] = cmd->ip;
3128
3129        return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params,
3130                               NULL);
3131}
3132
[f520a57]3133static int og_dbi_scope_get_computer(struct og_dbi *dbi, json_t *array,
3134                                     uint32_t room_id)
[c46fa3c]3135{
[91c3a28]3136        const char *computer_name, *computer_ip;
[f520a57]3137        uint32_t computer_id;
[3d253e6]3138        const char *msglog;
3139        dbi_result result;
[f520a57]3140        json_t *computer;
[3d253e6]3141
3142        result = dbi_conn_queryf(dbi->conn,
[f520a57]3143                                 "SELECT idordenador, nombreordenador, ip "
3144                                 "FROM ordenadores WHERE idaula=%d",
3145                                 room_id);
[3d253e6]3146        if (!result) {
3147                dbi_conn_error(dbi->conn, &msglog);
3148                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3149                       __func__, __LINE__, msglog);
3150                return -1;
3151        }
3152
3153        while (dbi_result_next_row(result)) {
[f520a57]3154                computer_id = dbi_result_get_uint(result, "idordenador");
[91c3a28]3155                computer_name = dbi_result_get_string(result, "nombreordenador");
3156                computer_ip = dbi_result_get_string(result, "ip");
[3d253e6]3157
[f520a57]3158                computer = json_object();
3159                if (!computer) {
[3d253e6]3160                        dbi_result_free(result);
3161                        return -1;
3162                }
3163
[f520a57]3164                json_object_set_new(computer, "name", json_string(computer_name));
3165                json_object_set_new(computer, "type", json_string("computer"));
3166                json_object_set_new(computer, "id", json_integer(computer_id));
3167                json_object_set_new(computer, "scope", json_array());
[91c3a28]3168                json_object_set_new(computer, "ip", json_string(computer_ip));
[f520a57]3169                json_array_append(array, computer);
3170                json_decref(computer);
[3d253e6]3171        }
3172        dbi_result_free(result);
3173
3174        return 0;
3175}
3176
[c46fa3c]3177static int og_dbi_scope_get_room(struct og_dbi *dbi, json_t *array,
3178                                 uint32_t center_id)
3179{
[3d253e6]3180        char room_name[OG_DB_ROOM_NAME_MAXLEN + 1] = {};
[f520a57]3181        json_t *room, *room_array;
[3d253e6]3182        const char *msglog;
3183        dbi_result result;
3184        uint32_t room_id;
3185
3186        result = dbi_conn_queryf(dbi->conn,
3187                                 "SELECT idaula, nombreaula FROM aulas WHERE "
3188                                 "idcentro=%d",
3189                                 center_id);
3190        if (!result) {
3191                dbi_conn_error(dbi->conn, &msglog);
3192                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3193                       __func__, __LINE__, msglog);
3194                return -1;
3195        }
3196
3197        while (dbi_result_next_row(result)) {
3198                room_id = dbi_result_get_uint(result, "idaula");
3199                strncpy(room_name,
3200                        dbi_result_get_string(result, "nombreaula"),
3201                        OG_DB_CENTER_NAME_MAXLEN);
3202
3203                room = json_object();
3204                if (!room) {
3205                        dbi_result_free(result);
3206                        return -1;
3207                }
3208
3209                json_object_set_new(room, "name", json_string(room_name));
3210                json_object_set_new(room, "type", json_string("room"));
3211                json_object_set_new(room, "id", json_integer(room_id));
3212                json_object_set_new(room, "scope", json_array());
3213                json_array_append(array, room);
3214                json_decref(room);
[f520a57]3215
3216                room_array = json_object_get(room, "scope");
3217                if (!room_array) {
3218                        dbi_result_free(result);
3219                        return -1;
3220                }
3221
3222                if (og_dbi_scope_get_computer(dbi, room_array, room_id)) {
3223                        dbi_result_free(result);
3224                        return -1;
3225                }
[3d253e6]3226        }
3227        dbi_result_free(result);
3228
3229        return 0;
3230}
3231
[f520a57]3232static int og_dbi_scope_get(struct og_dbi *dbi, json_t *array)
[c46fa3c]3233{
[f520a57]3234        char center_name[OG_DB_CENTER_NAME_MAXLEN + 1] = {};
3235        json_t *center, *array_room;
[3d253e6]3236        const char *msglog;
[f520a57]3237        uint32_t center_id;
[3d253e6]3238        dbi_result result;
3239
3240        result = dbi_conn_queryf(dbi->conn,
[f520a57]3241                                 "SELECT nombrecentro, idcentro FROM centros");
[3d253e6]3242        if (!result) {
3243                dbi_conn_error(dbi->conn, &msglog);
3244                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3245                       __func__, __LINE__, msglog);
3246                return -1;
3247        }
3248
3249        while (dbi_result_next_row(result)) {
[f520a57]3250                center_id = dbi_result_get_uint(result, "idcentro");
3251                strncpy(center_name,
3252                        dbi_result_get_string(result, "nombrecentro"),
[3d253e6]3253                        OG_DB_CENTER_NAME_MAXLEN);
3254
[f520a57]3255                center = json_object();
3256                if (!center) {
[3d253e6]3257                        dbi_result_free(result);
3258                        return -1;
3259                }
3260
[f520a57]3261                array_room = json_array();
3262                if (!array_room) {
3263                        dbi_result_free(result);
3264                        json_decref(center);
3265                        return -1;
3266                }
3267
3268                json_object_set_new(center, "name", json_string(center_name));
3269                json_object_set_new(center, "type", json_string("center"));
3270                json_object_set_new(center, "id", json_integer(center_id));
3271                json_object_set_new(center, "scope", array_room);
3272                json_array_append(array, center);
3273                json_decref(center);
3274
3275                if (og_dbi_scope_get_room(dbi, array_room, center_id)) {
3276                        dbi_result_free(result);
3277                        return -1;
3278                }
[3d253e6]3279        }
[f520a57]3280
[3d253e6]3281        dbi_result_free(result);
3282
3283        return 0;
3284}
3285
3286static int og_cmd_scope_get(json_t *element, struct og_msg_params *params,
3287                            char *buffer_reply)
3288{
3289        struct og_buffer og_buffer = {
3290                .data = buffer_reply
3291        };
[f520a57]3292        json_t *root, *array;
3293        struct og_dbi *dbi;
[3d253e6]3294
3295        root = json_object();
[76c0a05]3296        if (!root)
3297                return -1;
3298
[f520a57]3299        array = json_array();
3300        if (!array) {
[76c0a05]3301                json_decref(root);
[3d253e6]3302                return -1;
[76c0a05]3303        }
[f520a57]3304        json_object_set_new(root, "scope", array);
[3d253e6]3305
[fe1ce97]3306        dbi = og_dbi_open(&ogconfig.db);
[3d253e6]3307        if (!dbi) {
3308                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3309                       __func__, __LINE__);
[f520a57]3310                json_decref(root);
[3d253e6]3311                return -1;
3312        }
3313
[f520a57]3314        if (og_dbi_scope_get(dbi, array)) {
[3d253e6]3315                og_dbi_close(dbi);
[f520a57]3316                json_decref(root);
[3d253e6]3317                return -1;
3318        }
3319
3320        og_dbi_close(dbi);
3321
[2c6cef7]3322        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
3323                json_decref(root);
3324                return -1;
3325        }
3326
[3d253e6]3327        json_decref(root);
3328
3329        return 0;
3330}
3331
[04ca20e]3332int og_dbi_schedule_get(void)
3333{
3334        uint32_t schedule_id, task_id;
3335        struct og_schedule_time time;
3336        struct og_dbi *dbi;
3337        const char *msglog;
3338        dbi_result result;
3339
[fe1ce97]3340        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3341        if (!dbi) {
3342                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3343                       __func__, __LINE__);
3344                return -1;
3345        }
3346
3347        result = dbi_conn_queryf(dbi->conn,
3348                                 "SELECT idprogramacion, tipoaccion, identificador, "
3349                                 "sesion, annos, meses, diario, dias, semanas, horas, "
3350                                 "ampm, minutos FROM programaciones "
3351                                 "WHERE suspendida = 0");
3352        if (!result) {
3353                dbi_conn_error(dbi->conn, &msglog);
3354                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3355                       __func__, __LINE__, msglog);
3356                og_dbi_close(dbi);
3357                return -1;
3358        }
3359
3360        while (dbi_result_next_row(result)) {
3361                memset(&time, 0, sizeof(time));
3362                schedule_id = dbi_result_get_uint(result, "idprogramacion");
3363                task_id = dbi_result_get_uint(result, "identificador");
3364                time.years = dbi_result_get_uint(result, "annos");
3365                time.months = dbi_result_get_uint(result, "meses");
3366                time.weeks = dbi_result_get_uint(result, "semanas");
3367                time.week_days = dbi_result_get_uint(result, "dias");
3368                time.days = dbi_result_get_uint(result, "diario");
3369                time.hours = dbi_result_get_uint(result, "horas");
3370                time.am_pm = dbi_result_get_uint(result, "ampm");
3371                time.minutes = dbi_result_get_uint(result, "minutos");
[e68fefe]3372                time.check_stale = true;
[04ca20e]3373
3374                og_schedule_create(schedule_id, task_id, OG_SCHEDULE_TASK,
3375                                   &time);
3376        }
3377
3378        dbi_result_free(result);
3379        og_dbi_close(dbi);
3380
3381        return 0;
3382}
3383
3384static int og_dbi_schedule_create(struct og_dbi *dbi,
3385                                  struct og_msg_params *params,
3386                                  uint32_t *schedule_id,
3387                                  enum og_schedule_type schedule_type)
3388{
3389        uint8_t suspended = 0;
3390        uint32_t session = 0;
3391        const char *msglog;
3392        dbi_result result;
3393        uint8_t type;
3394
3395        switch (schedule_type) {
3396        case OG_SCHEDULE_TASK:
3397                type = 3;
3398                break;
3399        case OG_SCHEDULE_PROCEDURE:
3400                type = 2;
3401                break;
3402        case OG_SCHEDULE_COMMAND:
3403                session = atoi(params->task_id);
3404                type = 1;
3405                break;
3406        }
3407
3408        result = dbi_conn_queryf(dbi->conn,
3409                                 "INSERT INTO programaciones (tipoaccion,"
3410                                 " identificador, nombrebloque, annos, meses,"
3411                                 " semanas, dias, diario, horas, ampm, minutos,"
3412                                 " suspendida, sesion) VALUES (%d, %s, '%s',"
3413                                 " %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
3414                                 type, params->task_id, params->name,
3415                                 params->time.years, params->time.months,
3416                                 params->time.weeks, params->time.week_days,
3417                                 params->time.days, params->time.hours,
3418                                 params->time.am_pm, params->time.minutes,
3419                                 suspended, session);
3420        if (!result) {
3421                dbi_conn_error(dbi->conn, &msglog);
3422                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3423                       __func__, __LINE__, msglog);
3424                return -1;
3425        }
3426        dbi_result_free(result);
3427
3428        *schedule_id = dbi_conn_sequence_last(dbi->conn, NULL);
3429
3430        return 0;
3431}
3432
3433static int og_dbi_schedule_update(struct og_dbi *dbi,
3434                                  struct og_msg_params *params)
3435{
3436        const char *msglog;
3437        dbi_result result;
3438        uint8_t type = 3;
3439
3440        result = dbi_conn_queryf(dbi->conn,
3441                                 "UPDATE programaciones SET tipoaccion=%d, "
3442                                 "identificador='%s', nombrebloque='%s', "
3443                                 "annos=%d, meses=%d, "
3444                                 "diario=%d, horas=%d, ampm=%d, minutos=%d "
3445                                 "WHERE idprogramacion='%s'",
3446                                 type, params->task_id, params->name,
3447                                 params->time.years, params->time.months,
3448                                 params->time.days, params->time.hours,
3449                                 params->time.am_pm, params->time.minutes,
3450                                 params->id);
3451
3452        if (!result) {
3453                dbi_conn_error(dbi->conn, &msglog);
3454                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3455                       __func__, __LINE__, msglog);
3456                return -1;
3457        }
3458        dbi_result_free(result);
3459
3460        return 0;
3461}
3462
3463static int og_dbi_schedule_delete(struct og_dbi *dbi, uint32_t id)
3464{
3465        const char *msglog;
3466        dbi_result result;
3467
3468        result = dbi_conn_queryf(dbi->conn,
3469                                 "DELETE FROM programaciones WHERE idprogramacion=%d",
3470                                 id);
3471        if (!result) {
3472                dbi_conn_error(dbi->conn, &msglog);
3473                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3474                       __func__, __LINE__, msglog);
3475                return -1;
3476        }
3477        dbi_result_free(result);
3478
3479        return 0;
3480}
3481
3482struct og_db_schedule {
3483        uint32_t                id;
3484        uint32_t                task_id;
3485        const char              *name;
3486        struct og_schedule_time time;
3487        uint32_t                week_days;
3488        uint32_t                weeks;
3489        uint32_t                suspended;
3490        uint32_t                session;
3491};
3492
3493static int og_dbi_schedule_get_json(struct og_dbi *dbi, json_t *root,
3494                                    const char *task_id, const char *schedule_id)
3495{
3496        struct og_db_schedule schedule;
3497        json_t *obj, *array;
3498        const char *msglog;
3499        dbi_result result;
3500        int err = 0;
3501
3502        if (task_id) {
3503                result = dbi_conn_queryf(dbi->conn,
3504                                         "SELECT idprogramacion,"
3505                                         "       identificador, nombrebloque,"
3506                                         "       annos, meses, diario, dias,"
3507                                         "       semanas, horas, ampm,"
3508                                         "       minutos,suspendida, sesion "
3509                                         "FROM programaciones "
3510                                         "WHERE identificador=%d",
3511                                         atoi(task_id));
3512        } else if (schedule_id) {
3513                result = dbi_conn_queryf(dbi->conn,
3514                                         "SELECT idprogramacion,"
3515                                         "       identificador, nombrebloque,"
3516                                         "       annos, meses, diario, dias,"
3517                                         "       semanas, horas, ampm,"
3518                                         "       minutos,suspendida, sesion "
3519                                         "FROM programaciones "
3520                                         "WHERE idprogramacion=%d",
3521                                         atoi(schedule_id));
3522        } else {
3523                result = dbi_conn_queryf(dbi->conn,
3524                                         "SELECT idprogramacion,"
3525                                         "       identificador, nombrebloque,"
3526                                         "       annos, meses, diario, dias,"
3527                                         "       semanas, horas, ampm,"
3528                                         "       minutos,suspendida, sesion "
3529                                         "FROM programaciones");
3530        }
3531
3532        if (!result) {
3533                dbi_conn_error(dbi->conn, &msglog);
3534                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3535                       __func__, __LINE__, msglog);
3536                return -1;
3537        }
3538
3539        array = json_array();
3540        if (!array)
3541                return -1;
3542
3543        while (dbi_result_next_row(result)) {
3544                schedule.id = dbi_result_get_uint(result, "idprogramacion");
3545                schedule.task_id = dbi_result_get_uint(result, "identificador");
3546                schedule.name = dbi_result_get_string(result, "nombrebloque");
3547                schedule.time.years = dbi_result_get_uint(result, "annos");
3548                schedule.time.months = dbi_result_get_uint(result, "meses");
3549                schedule.time.days = dbi_result_get_uint(result, "diario");
3550                schedule.time.hours = dbi_result_get_uint(result, "horas");
3551                schedule.time.am_pm = dbi_result_get_uint(result, "ampm");
3552                schedule.time.minutes = dbi_result_get_uint(result, "minutos");
3553                schedule.week_days = dbi_result_get_uint(result, "dias");
3554                schedule.weeks = dbi_result_get_uint(result, "semanas");
3555                schedule.suspended = dbi_result_get_uint(result, "suspendida");
3556                schedule.session = dbi_result_get_uint(result, "sesion");
3557
3558                obj = json_object();
3559                if (!obj) {
3560                        err = -1;
3561                        break;
3562                }
3563                json_object_set_new(obj, "id", json_integer(schedule.id));
3564                json_object_set_new(obj, "task", json_integer(schedule.task_id));
3565                json_object_set_new(obj, "name", json_string(schedule.name));
3566                json_object_set_new(obj, "years", json_integer(schedule.time.years));
3567                json_object_set_new(obj, "months", json_integer(schedule.time.months));
3568                json_object_set_new(obj, "days", json_integer(schedule.time.days));
3569                json_object_set_new(obj, "hours", json_integer(schedule.time.hours));
3570                json_object_set_new(obj, "am_pm", json_integer(schedule.time.am_pm));
3571                json_object_set_new(obj, "minutes", json_integer(schedule.time.minutes));
3572                json_object_set_new(obj, "week_days", json_integer(schedule.week_days));
3573                json_object_set_new(obj, "weeks", json_integer(schedule.weeks));
3574                json_object_set_new(obj, "suspended", json_integer(schedule.suspended));
3575                json_object_set_new(obj, "session", json_integer(schedule.session));
3576
3577                json_array_append_new(array, obj);
3578        }
3579
3580        json_object_set_new(root, "schedule", array);
3581
3582        dbi_result_free(result);
3583
3584        return err;
3585}
3586
3587static int og_task_schedule_create(struct og_msg_params *params)
3588{
3589        enum og_schedule_type type;
3590        uint32_t schedule_id;
3591        struct og_dbi *dbi;
3592        int err;
3593
3594        if (!strcmp(params->type, "task"))
3595                type = OG_SCHEDULE_TASK;
3596        else if (!strcmp(params->type, "procedure"))
3597                type = OG_SCHEDULE_PROCEDURE;
3598        else if (!strcmp(params->type, "command"))
3599                type = OG_SCHEDULE_COMMAND;
3600        else
3601                return -1;
3602
[fe1ce97]3603        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3604        if (!dbi) {
3605                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3606                       __func__, __LINE__);
3607                return -1;
3608        }
3609
3610        err = og_dbi_schedule_create(dbi, params, &schedule_id, type);
3611        if (err < 0) {
3612                og_dbi_close(dbi);
3613                return -1;
3614        }
3615        og_schedule_create(schedule_id, atoi(params->task_id), type,
3616                           &params->time);
3617        og_schedule_refresh(og_loop);
3618        og_dbi_close(dbi);
3619
3620        return 0;
3621}
3622
[e68fefe]3623static uint32_t og_tm_years_mask(struct tm *tm)
3624{
3625        int i, j = 0;
3626
3627        for (i = 2010; i < 2026; i++, j++) {
3628                if (tm->tm_year + 1900 == i)
3629                        break;
3630        }
3631
3632        return (1 << j);
3633}
3634
3635static uint32_t og_tm_months_mask(struct tm *tm)
3636{
3637        return 1 << tm->tm_mon;
3638}
3639
[41bc66d]3640static uint16_t og_tm_hours_mask(struct tm *tm)
[e68fefe]3641{
[41bc66d]3642        return tm->tm_hour >= 12 ? 1 << (tm->tm_hour - 12) : 1 << tm->tm_hour;
[e68fefe]3643}
3644
3645static uint32_t og_tm_ampm(struct tm *tm)
3646{
3647        return tm->tm_hour < 12 ? 0 : 1;
3648}
3649
3650static uint32_t og_tm_days_mask(struct tm *tm)
3651{
3652        return 1 << (tm->tm_mday - 1);
3653}
3654
3655static void og_schedule_time_now(struct og_schedule_time *ogtime)
3656{
3657        struct tm *tm;
3658        time_t now;
3659
3660        now = time(NULL);
3661        tm = localtime(&now);
3662
3663        ogtime->years = og_tm_years_mask(tm);
3664        ogtime->months = og_tm_months_mask(tm);
3665        ogtime->weeks = 0;
3666        ogtime->week_days = 0;
3667        ogtime->days =  og_tm_days_mask(tm);
3668        ogtime->hours = og_tm_hours_mask(tm);
3669        ogtime->am_pm = og_tm_ampm(tm);
3670        ogtime->minutes = tm->tm_min;
3671}
3672
[04ca20e]3673static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params)
3674{
[e68fefe]3675        bool when = false;
[04ca20e]3676        const char *key;
3677        json_t *value;
[e7e80cd]3678        int err = 0;
[04ca20e]3679
3680        if (json_typeof(element) != JSON_OBJECT)
3681                return -1;
3682
3683        json_object_foreach(element, key, value) {
3684                if (!strcmp(key, "task")) {
3685                        err = og_json_parse_string(value, &params->task_id);
3686                        params->flags |= OG_REST_PARAM_TASK;
3687                } else if (!strcmp(key, "name")) {
3688                        err = og_json_parse_string(value, &params->name);
3689                        params->flags |= OG_REST_PARAM_NAME;
3690                } else if (!strcmp(key, "when")) {
3691                        err = og_json_parse_time_params(value, params);
[e68fefe]3692                        when = true;
[04ca20e]3693                } else if (!strcmp(key, "type")) {
3694                        err = og_json_parse_string(value, &params->type);
3695                        params->flags |= OG_REST_PARAM_TYPE;
3696                }
3697
3698                if (err < 0)
[e7e80cd]3699                        return err;
[04ca20e]3700        }
3701
[e68fefe]3702        if (!when) {
3703                params->time.check_stale = false;
3704                og_schedule_time_now(&params->time);
3705                params->flags |= OG_REST_PARAM_TIME_YEARS |
3706                                 OG_REST_PARAM_TIME_MONTHS |
3707                                 OG_REST_PARAM_TIME_WEEKS |
3708                                 OG_REST_PARAM_TIME_WEEK_DAYS |
3709                                 OG_REST_PARAM_TIME_DAYS |
3710                                 OG_REST_PARAM_TIME_HOURS |
3711                                 OG_REST_PARAM_TIME_AM_PM |
3712                                 OG_REST_PARAM_TIME_MINUTES;
3713        } else {
3714                params->time.check_stale = true;
3715        }
3716
[04ca20e]3717        if (!og_msg_params_validate(params, OG_REST_PARAM_TASK |
3718                                            OG_REST_PARAM_NAME |
3719                                            OG_REST_PARAM_TIME_YEARS |
3720                                            OG_REST_PARAM_TIME_MONTHS |
3721                                            OG_REST_PARAM_TIME_WEEKS |
3722                                            OG_REST_PARAM_TIME_WEEK_DAYS |
3723                                            OG_REST_PARAM_TIME_DAYS |
3724                                            OG_REST_PARAM_TIME_HOURS |
3725                                            OG_REST_PARAM_TIME_MINUTES |
3726                                            OG_REST_PARAM_TIME_AM_PM |
3727                                            OG_REST_PARAM_TYPE))
3728                return -1;
3729
3730        return og_task_schedule_create(params);
3731}
3732
3733static int og_cmd_schedule_update(json_t *element, struct og_msg_params *params)
3734{
3735        struct og_dbi *dbi;
[8b7b5f3]3736        bool when = false;
[04ca20e]3737        const char *key;
3738        json_t *value;
[e7e80cd]3739        int err = 0;
[04ca20e]3740
3741        if (json_typeof(element) != JSON_OBJECT)
3742                return -1;
3743
3744        json_object_foreach(element, key, value) {
3745                if (!strcmp(key, "id")) {
3746                        err = og_json_parse_string(value, &params->id);
3747                        params->flags |= OG_REST_PARAM_ID;
3748                } else if (!strcmp(key, "task")) {
3749                        err = og_json_parse_string(value, &params->task_id);
3750                        params->flags |= OG_REST_PARAM_TASK;
3751                } else if (!strcmp(key, "name")) {
3752                        err = og_json_parse_string(value, &params->name);
3753                        params->flags |= OG_REST_PARAM_NAME;
[8b7b5f3]3754                } else if (!strcmp(key, "when")) {
[04ca20e]3755                        err = og_json_parse_time_params(value, params);
[8b7b5f3]3756                        when = true;
3757                }
[04ca20e]3758
3759                if (err < 0)
[e7e80cd]3760                        return err;
[04ca20e]3761        }
3762
[8b7b5f3]3763        if (!when) {
3764                params->time.check_stale = false;
3765                og_schedule_time_now(&params->time);
3766                params->flags |= OG_REST_PARAM_TIME_YEARS |
3767                                 OG_REST_PARAM_TIME_MONTHS |
3768                                 OG_REST_PARAM_TIME_WEEKS |
3769                                 OG_REST_PARAM_TIME_WEEK_DAYS |
3770                                 OG_REST_PARAM_TIME_DAYS |
3771                                 OG_REST_PARAM_TIME_HOURS |
3772                                 OG_REST_PARAM_TIME_AM_PM |
3773                                 OG_REST_PARAM_TIME_MINUTES;
3774        } else {
3775                params->time.check_stale = true;
3776        }
3777
[04ca20e]3778        if (!og_msg_params_validate(params, OG_REST_PARAM_ID |
3779                                            OG_REST_PARAM_TASK |
3780                                            OG_REST_PARAM_NAME |
3781                                            OG_REST_PARAM_TIME_YEARS |
3782                                            OG_REST_PARAM_TIME_MONTHS |
3783                                            OG_REST_PARAM_TIME_DAYS |
3784                                            OG_REST_PARAM_TIME_HOURS |
3785                                            OG_REST_PARAM_TIME_MINUTES |
3786                                            OG_REST_PARAM_TIME_AM_PM))
3787                return -1;
3788
[fe1ce97]3789        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3790        if (!dbi) {
3791                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3792                           __func__, __LINE__);
3793                return -1;
3794        }
3795
3796        err = og_dbi_schedule_update(dbi, params);
3797        og_dbi_close(dbi);
3798
3799        if (err < 0)
3800                return err;
3801
3802        og_schedule_update(og_loop, atoi(params->id), atoi(params->task_id),
3803                           &params->time);
3804        og_schedule_refresh(og_loop);
3805
3806        return err;
3807}
3808
3809static int og_cmd_schedule_delete(json_t *element, struct og_msg_params *params)
3810{
3811        struct og_dbi *dbi;
3812        const char *key;
3813        json_t *value;
[e7e80cd]3814        int err = 0;
[04ca20e]3815
3816        if (json_typeof(element) != JSON_OBJECT)
3817                return -1;
3818
3819        json_object_foreach(element, key, value) {
3820                if (!strcmp(key, "id")) {
3821                        err = og_json_parse_string(value, &params->id);
3822                        params->flags |= OG_REST_PARAM_ID;
3823                }
3824
3825                if (err < 0)
[e7e80cd]3826                        return err;
[04ca20e]3827        }
3828
3829        if (!og_msg_params_validate(params, OG_REST_PARAM_ID))
3830                return -1;
3831
[fe1ce97]3832        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3833        if (!dbi) {
3834                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3835                           __func__, __LINE__);
3836                return -1;
3837        }
3838
3839        err = og_dbi_schedule_delete(dbi, atoi(params->id));
3840        og_dbi_close(dbi);
3841
3842        og_schedule_delete(og_loop, atoi(params->id));
3843
3844        return err;
3845}
3846
3847static int og_cmd_schedule_get(json_t *element, struct og_msg_params *params,
3848                               char *buffer_reply)
3849{
3850        struct og_buffer og_buffer = {
3851                .data   = buffer_reply,
3852        };
3853        json_t *schedule_root;
3854        struct og_dbi *dbi;
3855        const char *key;
3856        json_t *value;
[e7e80cd]3857        int err = 0;
[04ca20e]3858
3859        if (element) {
3860                if (json_typeof(element) != JSON_OBJECT)
3861                        return -1;
3862
3863                json_object_foreach(element, key, value) {
3864                        if (!strcmp(key, "task")) {
3865                                err = og_json_parse_string(value,
3866                                                           &params->task_id);
3867                        } else if (!strcmp(key, "id")) {
3868                                err = og_json_parse_string(value, &params->id);
3869                        }
3870
3871                        if (err < 0)
[e7e80cd]3872                                return err;
[04ca20e]3873                }
3874        }
3875
[fe1ce97]3876        dbi = og_dbi_open(&ogconfig.db);
[04ca20e]3877        if (!dbi) {
3878                syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
3879                           __func__, __LINE__);
3880                return -1;
3881        }
3882
3883        schedule_root = json_object();
3884        if (!schedule_root) {
3885                og_dbi_close(dbi);
3886                return -1;
3887        }
3888
3889        err = og_dbi_schedule_get_json(dbi, schedule_root,
3890                                       params->task_id, params->id);
3891        og_dbi_close(dbi);
3892
3893        if (err >= 0)
[2c6cef7]3894                err = json_dump_callback(schedule_root, og_json_dump_clients,
3895                                         &og_buffer, 0);
[04ca20e]3896
3897        json_decref(schedule_root);
3898
3899        return err;
3900}
3901
[8015f85]3902#define OG_LIVE_JSON_FILE_PATH "/opt/opengnsys/etc/ogliveinfo.json"
3903
3904static int og_cmd_oglive_list(char *buffer_reply)
3905{
3906        struct og_buffer og_buffer = {
3907                .data = buffer_reply
3908        };
3909        json_error_t json_err;
3910        json_t *root;
3911
3912        root = json_load_file(OG_LIVE_JSON_FILE_PATH, 0, &json_err);
3913        if (!root) {
3914                syslog(LOG_ERR, "malformed json line %d: %s\n",
3915                       json_err.line, json_err.text);
3916                return -1;
3917        }
3918
[2c6cef7]3919        if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
3920                json_decref(root);
3921                return -1;
3922        }
3923
[8015f85]3924        json_decref(root);
3925
3926        return 0;
3927}
3928
[0212091]3929static int og_cmd_post_center_add(json_t *element,
3930                                  struct og_msg_params *params,
3931                                  char *buffer_reply)
3932{
3933        const char *key, *msglog;
3934        struct og_dbi *dbi;
3935        dbi_result result;
3936        json_t *value;
3937        int err = 0;
3938
3939        json_object_foreach(element, key, value) {
3940                if (!strcmp(key, "name")) {
3941                        err = og_json_parse_string(value, &params->name);
3942                        params->flags |= OG_REST_PARAM_NAME;
3943                } else if (!strcmp(key, "comment")) {
3944                        err = og_json_parse_string(value, &params->comment);
3945                }
3946
3947                if (err < 0)
3948                        return err;
3949        }
3950
3951        if (!og_msg_params_validate(params, OG_REST_PARAM_NAME))
3952                return -1;
3953        if (!params->comment)
3954                params->comment = "";
3955
3956        dbi = og_dbi_open(&ogconfig.db);
3957        if (!dbi) {
3958                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
3959                       __func__, __LINE__);
3960                return -1;
3961        }
3962
3963        result = dbi_conn_queryf(dbi->conn,
3964                                 "SELECT nombrecentro FROM centros WHERE nombrecentro='%s'",
3965                                 params->name);
3966
3967        if (!result) {
3968                dbi_conn_error(dbi->conn, &msglog);
3969                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
3970                       __func__, __LINE__, msglog);
3971                og_dbi_close(dbi);
3972                return -1;
3973        }
3974
3975        if (dbi_result_get_numrows(result) > 0) {
3976                syslog(LOG_ERR, "Center with name %s already exists\n",
3977                       params->name);
3978                dbi_result_free(result);
3979                og_dbi_close(dbi);
3980                return -1;
3981        }
3982        dbi_result_free(result);
3983
3984        result = dbi_conn_queryf(dbi->conn,
3985                                 "INSERT INTO centros("
3986                                 "  nombrecentro,"
3987                                 "  comentarios,"
3988                                 "  identidad) VALUES ("
3989                                 "'%s', '%s', 1)",
3990                                 params->name, params->comment);
3991
3992        if (!result) {
3993                dbi_conn_error(dbi->conn, &msglog);
3994                syslog(LOG_ERR, "failed to add center to database (%s:%d) %s\n",
3995                       __func__, __LINE__, msglog);
3996                og_dbi_close(dbi);
3997                return -1;
3998        }
3999
4000        dbi_result_free(result);
4001        og_dbi_close(dbi);
4002        return 0;
4003}
4004
[29e7641]4005static int og_cmd_post_room_add(json_t *element,
4006                                struct og_msg_params *params)
4007{
4008        struct og_room room = {};
4009        const char *key, *msglog;
4010        struct og_dbi *dbi;
4011        dbi_result result;
4012        json_t *value;
4013        int err = 0;
4014
4015        json_object_foreach(element, key, value) {
4016                if (!strcmp(key, "name")) {
4017                        err = og_json_parse_string_copy(value, room.name,
4018                                                        sizeof(room.name));
4019                        params->flags |= OG_REST_PARAM_NAME;
4020                } else if (!strcmp(key, "location")) {
4021                        err = og_json_parse_string_copy(value, room.location,
4022                                                        sizeof(room.location));
4023                } else if (!strcmp(key, "gateway")) {
4024                        err = og_json_parse_string_copy(value, room.gateway,
4025                                                        sizeof(room.gateway));
4026                } else if (!strcmp(key, "netmask")) {
4027                        err = og_json_parse_string_copy(value, room.netmask,
4028                                                        sizeof(room.netmask));
4029                        params->flags |= OG_REST_PARAM_NETMASK;
4030                } else if (!strcmp(key, "ntp")) {
4031                        err = og_json_parse_string_copy(value, room.ntp,
4032                                                        sizeof(room.ntp));
4033                } else if (!strcmp(key, "dns")) {
4034                        err = og_json_parse_string_copy(value, room.dns,
4035                                                        sizeof(room.dns));
4036                } else if (!strcmp(key, "center")) {
4037                        err = og_json_parse_uint(value, &room.center);
4038                        params->flags |= OG_REST_PARAM_CENTER;
4039                } else if (!strcmp(key, "group")) {
4040                        err = og_json_parse_uint(value, &room.group);
4041                } else if (!strcmp(key, "remote")) {
4042                        err = og_json_parse_bool(value, &room.remote);
4043                }
4044
4045                if (err < 0)
4046                        return err;
4047        }
4048
4049        if (!og_msg_params_validate(params, OG_REST_PARAM_NAME |
4050                                            OG_REST_PARAM_NETMASK |
4051                                            OG_REST_PARAM_CENTER))
4052                return -1;
4053
4054        dbi = og_dbi_open(&ogconfig.db);
4055        if (!dbi) {
4056                syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
4057                       __func__, __LINE__);
4058                return -1;
4059        }
4060
4061        result = dbi_conn_queryf(dbi->conn,
4062                                 "SELECT nombreaula FROM aulas "
4063                                 "WHERE nombreaula='%s' AND idcentro=%d",
4064                                 room.name, room.center);
4065
4066        if (!result) {
4067                dbi_conn_error(dbi->conn, &msglog);
4068                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
4069                       __func__, __LINE__, msglog);
4070                og_dbi_close(dbi);
4071                return -1;
4072        }
4073
4074        if (dbi_result_get_numrows(result) > 0) {
4075                syslog(LOG_ERR, "Room with name %s already exists in the "
4076                                "center with id %d\n",
4077                       room.name, room.center);
4078                dbi_result_free(result);
4079                og_dbi_close(dbi);
4080                return -1;
4081        }
4082        dbi_result_free(result);
4083
4084        result = dbi_conn_queryf(dbi->conn,
4085                                 "INSERT INTO aulas("
4086                                 "  idcentro,"
4087                                 "  nombreaula,"
4088                                 "  netmask,"
4089                                 "  grupoid,"
4090                                 "  ubicacion,"
4091                                 "  router,"
4092                                 "  dns,"
4093                                 "  ntp,"
4094                                 "  inremotepc) VALUES ("
4095                                 "%d, '%s', '%s', %d, '%s', "
4096                                 "'%s', '%s', '%s', %d)",
4097                                 room.center, room.name, room.netmask,
4098                                 room.group, room.location, room.gateway,
4099                                 room.dns, room.ntp, room.remote);
4100
4101        if (!result) {
4102                dbi_conn_error(dbi->conn, &msglog);
4103                syslog(LOG_ERR, "failed to add room to database (%s:%d) %s\n",
4104                       __func__, __LINE__, msglog);
4105                og_dbi_close(dbi);
4106                return -1;
4107        }
4108
4109        dbi_result_free(result);
4110        og_dbi_close(dbi);
4111        return 0;
4112}
4113
[04ca20e]4114static int og_client_method_not_found(struct og_client *cli)
4115{
4116        /* To meet RFC 7231, this function MUST generate an Allow header field
4117         * containing the correct methods. For example: "Allow: POST\r\n"
4118         */
4119        char buf[] = "HTTP/1.1 405 Method Not Allowed\r\n"
4120                     "Content-Length: 0\r\n\r\n";
4121
4122        send(og_client_socket(cli), buf, strlen(buf), 0);
4123
4124        return -1;
4125}
4126
4127static int og_client_bad_request(struct og_client *cli)
4128{
4129        char buf[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n";
4130
4131        send(og_client_socket(cli), buf, strlen(buf), 0);
4132
4133        return -1;
4134}
4135
4136static int og_client_not_found(struct og_client *cli)
4137{
4138        char buf[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
4139
4140        send(og_client_socket(cli), buf, strlen(buf), 0);
4141
4142        return -1;
4143}
4144
4145static int og_client_not_authorized(struct og_client *cli)
4146{
4147        char buf[] = "HTTP/1.1 401 Unauthorized\r\n"
4148                     "WWW-Authenticate: Basic\r\n"
4149                     "Content-Length: 0\r\n\r\n";
4150
4151        send(og_client_socket(cli), buf, strlen(buf), 0);
4152
4153        return -1;
4154}
4155
4156static int og_server_internal_error(struct og_client *cli)
4157{
4158        char buf[] = "HTTP/1.1 500 Internal Server Error\r\n"
4159                     "Content-Length: 0\r\n\r\n";
4160
4161        send(og_client_socket(cli), buf, strlen(buf), 0);
4162
4163        return -1;
4164}
4165
4166static int og_client_ok(struct og_client *cli, char *buf_reply)
4167{
4168        char buf[OG_MSG_RESPONSE_MAXLEN] = {};
[90eab86]4169        int len;
[04ca20e]4170
4171        len = snprintf(buf, sizeof(buf),
4172                       "HTTP/1.1 200 OK\r\nContent-Length: %ld\r\n\r\n%s",
4173                       strlen(buf_reply), buf_reply);
[90eab86]4174        if (len >= (int)sizeof(buf)) {
4175                syslog(LOG_ERR, "HTTP response to %s:%hu is too large\n",
4176                       inet_ntoa(cli->addr.sin_addr),
4177                       ntohs(cli->addr.sin_port));
4178                return og_server_internal_error(cli);
4179        }
[04ca20e]4180
4181        send(og_client_socket(cli), buf, strlen(buf), 0);
4182
[90eab86]4183        return 0;
[04ca20e]4184}
4185
4186int og_client_state_process_payload_rest(struct og_client *cli)
4187{
4188        char buf_reply[OG_MSG_RESPONSE_MAXLEN] = {};
4189        struct og_msg_params params = {};
4190        enum og_rest_method method;
4191        const char *cmd, *body;
4192        json_error_t json_err;
4193        json_t *root = NULL;
4194        int err = 0;
4195
4196        syslog(LOG_DEBUG, "%s:%hu %.32s ...\n",
4197               inet_ntoa(cli->addr.sin_addr),
4198               ntohs(cli->addr.sin_port), cli->buf);
4199
4200        if (!strncmp(cli->buf, "GET", strlen("GET"))) {
4201                method = OG_METHOD_GET;
4202                cmd = cli->buf + strlen("GET") + 2;
4203        } else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
4204                method = OG_METHOD_POST;
4205                cmd = cli->buf + strlen("POST") + 2;
4206        } else
4207                return og_client_method_not_found(cli);
4208
4209        body = strstr(cli->buf, "\r\n\r\n") + 4;
4210
[fe1ce97]4211        if (strcmp(cli->auth_token, ogconfig.rest.api_token)) {
[04ca20e]4212                syslog(LOG_ERR, "wrong Authentication key\n");
4213                return og_client_not_authorized(cli);
4214        }
4215
4216        if (cli->content_length) {
4217                root = json_loads(body, 0, &json_err);
4218                if (!root) {
4219                        syslog(LOG_ERR, "malformed json line %d: %s\n",
4220                               json_err.line, json_err.text);
4221                        return og_client_not_found(cli);
4222                }
4223        }
4224
4225        if (!strncmp(cmd, "clients", strlen("clients"))) {
4226                if (method != OG_METHOD_POST &&
[9b708e0]4227                    method != OG_METHOD_GET) {
4228                        err = og_client_method_not_found(cli);
4229                        goto err_process_rest_payload;
4230                }
[04ca20e]4231
4232                if (method == OG_METHOD_POST && !root) {
4233                        syslog(LOG_ERR, "command clients with no payload\n");
[9b708e0]4234                        err = og_client_bad_request(cli);
4235                        goto err_process_rest_payload;
[04ca20e]4236                }
4237                switch (method) {
4238                case OG_METHOD_POST:
4239                        err = og_cmd_post_clients(root, &params);
4240                        break;
4241                case OG_METHOD_GET:
4242                        err = og_cmd_get_clients(root, &params, buf_reply);
4243                        break;
4244                default:
[9b708e0]4245                        err = og_client_bad_request(cli);
4246                        goto err_process_rest_payload;
[04ca20e]4247                }
[b59ff7c]4248        } else if (!strncmp(cmd, "client/setup",
4249                            strlen("client/setup"))) {
[9b708e0]4250                if (method != OG_METHOD_GET) {
4251                        err = og_client_method_not_found(cli);
4252                        goto err_process_rest_payload;
4253                }
[b59ff7c]4254
4255                if (!root) {
4256                        syslog(LOG_ERR,
4257                               "command client partitions with no payload\n");
[9b708e0]4258                        err = og_client_bad_request(cli);
4259                        goto err_process_rest_payload;
[b59ff7c]4260                }
4261
4262                err = og_cmd_get_client_setup(root, &params, buf_reply);
[af47a08]4263        } else if (!strncmp(cmd, "client/info",
4264                            strlen("client/info"))) {
[9b708e0]4265                if (method != OG_METHOD_GET) {
4266                        err = og_client_method_not_found(cli);
4267                        goto err_process_rest_payload;
4268                }
[af47a08]4269                if (!root) {
4270                        syslog(LOG_ERR,
4271                               "command client info with no payload\n");
[9b708e0]4272                        err = og_client_bad_request(cli);
4273                        goto err_process_rest_payload;
[af47a08]4274                }
4275
4276                err = og_cmd_get_client_info(root, &params, buf_reply);
[65a14e5]4277        } else if (!strncmp(cmd, "client/add", strlen("client/add"))) {
[9b708e0]4278                if (method != OG_METHOD_POST) {
4279                        err = og_client_method_not_found(cli);
4280                        goto err_process_rest_payload;
4281                }
[65a14e5]4282
4283                if (!root) {
4284                        syslog(LOG_ERR,
4285                               "command client info with no payload\n");
[9b708e0]4286                        err = og_client_bad_request(cli);
4287                        goto err_process_rest_payload;
[65a14e5]4288                }
4289
4290                err = og_cmd_post_client_add(root, &params, buf_reply);
[24c8b94]4291        } else if (!strncmp(cmd, "client/delete", strlen("client/delete"))) {
[9b708e0]4292                if (method != OG_METHOD_POST) {
4293                        err = og_client_method_not_found(cli);
4294                        goto err_process_rest_payload;
4295                }
[24c8b94]4296
4297                if (!root) {
4298                        syslog(LOG_ERR,
4299                               "command client delete with no payload\n");
[9b708e0]4300                        err = og_client_bad_request(cli);
4301                        goto err_process_rest_payload;
[24c8b94]4302                }
4303
4304                err = og_cmd_post_client_delete(root, &params);
[04ca20e]4305        } else if (!strncmp(cmd, "wol", strlen("wol"))) {
[9b708e0]4306                if (method != OG_METHOD_POST) {
4307                        err = og_client_method_not_found(cli);
4308                        goto err_process_rest_payload;
4309                }
[04ca20e]4310
4311                if (!root) {
4312                        syslog(LOG_ERR, "command wol with no payload\n");
[9b708e0]4313                        err = og_client_bad_request(cli);
4314                        goto err_process_rest_payload;
[04ca20e]4315                }
4316                err = og_cmd_wol(root, &params);
4317        } else if (!strncmp(cmd, "shell/run", strlen("shell/run"))) {
[9b708e0]4318                if (method != OG_METHOD_POST) {
4319                        err = og_client_method_not_found(cli);
4320                        goto err_process_rest_payload;
4321                }
[04ca20e]4322
4323                if (!root) {
4324                        syslog(LOG_ERR, "command run with no payload\n");
[9b708e0]4325                        err = og_client_bad_request(cli);
4326                        goto err_process_rest_payload;
[04ca20e]4327                }
4328                err = og_cmd_run_post(root, &params);
4329        } else if (!strncmp(cmd, "shell/output", strlen("shell/output"))) {
[9b708e0]4330                if (method != OG_METHOD_POST) {
4331                        err = og_client_method_not_found(cli);
4332                        goto err_process_rest_payload;
4333                }
[04ca20e]4334
4335                if (!root) {
4336                        syslog(LOG_ERR, "command output with no payload\n");
[9b708e0]4337                        err = og_client_bad_request(cli);
4338                        goto err_process_rest_payload;
[04ca20e]4339                }
4340
4341                err = og_cmd_run_get(root, &params, buf_reply);
4342        } else if (!strncmp(cmd, "session", strlen("session"))) {
[9b708e0]4343                if (method != OG_METHOD_POST && method != OG_METHOD_GET) {
4344                        err = og_client_method_not_found(cli);
4345                        goto err_process_rest_payload;
4346                }
[04ca20e]4347
4348                if (!root) {
4349                        syslog(LOG_ERR, "command session with no payload\n");
[9b708e0]4350                        err = og_client_bad_request(cli);
4351                        goto err_process_rest_payload;
[04ca20e]4352                }
[7f5ab4a]4353
4354                if (method == OG_METHOD_POST)
4355                        err = og_cmd_session(root, &params);
4356                else
4357                        err = og_cmd_get_session(root, &params, buf_reply);
[3d253e6]4358        } else if (!strncmp(cmd, "scopes", strlen("scopes"))) {
[9b708e0]4359                if (method != OG_METHOD_GET) {
4360                        err = og_client_method_not_found(cli);
4361                        goto err_process_rest_payload;
4362                }
[3d253e6]4363
[aeb53bd]4364                if (root) {
4365                        syslog(LOG_ERR, "command scopes with payload\n");
[9b708e0]4366                        err = og_client_bad_request(cli);
4367                        goto err_process_rest_payload;
[aeb53bd]4368                }
4369
[3d253e6]4370                err = og_cmd_scope_get(root, &params, buf_reply);
[04ca20e]4371        } else if (!strncmp(cmd, "poweroff", strlen("poweroff"))) {
[9b708e0]4372                if (method != OG_METHOD_POST) {
4373                        err = og_client_method_not_found(cli);
4374                        goto err_process_rest_payload;
4375                }
[04ca20e]4376
4377                if (!root) {
4378                        syslog(LOG_ERR, "command poweroff with no payload\n");
[9b708e0]4379                        err = og_client_bad_request(cli);
4380                        goto err_process_rest_payload;
[04ca20e]4381                }
4382                err = og_cmd_poweroff(root, &params);
4383        } else if (!strncmp(cmd, "reboot", strlen("reboot"))) {
[9b708e0]4384                if (method != OG_METHOD_POST) {
4385                        err = og_client_method_not_found(cli);
4386                        goto err_process_rest_payload;
4387                }
[04ca20e]4388
4389                if (!root) {
4390                        syslog(LOG_ERR, "command reboot with no payload\n");
[9b708e0]4391                        err = og_client_bad_request(cli);
4392                        goto err_process_rest_payload;
[04ca20e]4393                }
4394                err = og_cmd_reboot(root, &params);
[b8a509b]4395        } else if (!strncmp(cmd, "mode", strlen("mode"))) {
[9b708e0]4396                if (method != OG_METHOD_GET && method != OG_METHOD_POST) {
4397                        err = og_client_method_not_found(cli);
4398                        goto err_process_rest_payload;
4399                }
[608709f]4400
[33b0c6f]4401                if (method == OG_METHOD_POST && !root) {
[b8a509b]4402                        syslog(LOG_ERR, "command mode with no payload\n");
[9b708e0]4403                        err = og_client_bad_request(cli);
4404                        goto err_process_rest_payload;
[33b0c6f]4405                }
4406
4407                if (method == OG_METHOD_GET)
4408                        err = og_cmd_get_modes(root, &params, buf_reply);
4409                else if (method == OG_METHOD_POST)
4410                        err = og_cmd_post_modes(root, &params);
[04ca20e]4411        } else if (!strncmp(cmd, "stop", strlen("stop"))) {
[9b708e0]4412                if (method != OG_METHOD_POST) {
4413                        err = og_client_method_not_found(cli);
4414                        goto err_process_rest_payload;
4415                }
[04ca20e]4416
4417                if (!root) {
4418                        syslog(LOG_ERR, "command stop with no payload\n");
[9b708e0]4419                        err = og_client_bad_request(cli);
4420                        goto err_process_rest_payload;
[04ca20e]4421                }
4422                err = og_cmd_stop(root, &params);
4423        } else if (!strncmp(cmd, "refresh", strlen("refresh"))) {
[9b708e0]4424                if (method != OG_METHOD_POST) {
4425                        err = og_client_method_not_found(cli);
4426                        goto err_process_rest_payload;
4427                }
[04ca20e]4428
4429                if (!root) {
4430                        syslog(LOG_ERR, "command refresh with no payload\n");
[9b708e0]4431                        err = og_client_bad_request(cli);
4432                        goto err_process_rest_payload;
[04ca20e]4433                }
4434                err = og_cmd_refresh(root, &params);
4435        } else if (!strncmp(cmd, "hardware", strlen("hardware"))) {
[9b708e0]4436                if (method != OG_METHOD_GET && method != OG_METHOD_POST) {
4437                        err = og_client_method_not_found(cli);
4438                        goto err_process_rest_payload;
4439                }
[04ca20e]4440
4441                if (!root) {
4442                        syslog(LOG_ERR, "command hardware with no payload\n");
[9b708e0]4443                        err = og_client_bad_request(cli);
4444                        goto err_process_rest_payload;
[04ca20e]4445                }
[a8eccba]4446
4447                if (method == OG_METHOD_GET)
4448                        err = og_cmd_get_hardware(root, &params, buf_reply);
4449                else if (method == OG_METHOD_POST)
4450                        err = og_cmd_hardware(root, &params);
[04ca20e]4451        } else if (!strncmp(cmd, "software", strlen("software"))) {
[9b708e0]4452                if (method != OG_METHOD_POST && method != OG_METHOD_GET) {
4453                        err = og_client_method_not_found(cli);
4454                        goto err_process_rest_payload;
4455                }
[04ca20e]4456
4457                if (!root) {
4458                        syslog(LOG_ERR, "command software with no payload\n");
[9b708e0]4459                        err = og_client_bad_request(cli);
4460                        goto err_process_rest_payload;
[04ca20e]4461                }
[25c1c16]4462
4463                if (method == OG_METHOD_POST)
4464                        err = og_cmd_software(root, &params);
4465                else
4466                        err = og_cmd_get_software(root, &params, buf_reply);
[403e7c3]4467        } else if (!strncmp(cmd, "images", strlen("images"))) {
[9b708e0]4468                if (method != OG_METHOD_GET) {
4469                        err = og_client_method_not_found(cli);
4470                        goto err_process_rest_payload;
4471                }
[403e7c3]4472
[9b708e0]4473                if (root) {
[d9e1521]4474                        err = og_client_bad_request(cli);
[9b708e0]4475                        goto err_process_rest_payload;
4476                }
4477
4478                err = og_cmd_images(buf_reply);
[04ca20e]4479        } else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
[9b708e0]4480                if (method != OG_METHOD_POST) {
4481                        err = og_client_method_not_found(cli);
4482                        goto err_process_rest_payload;
4483                }
[04ca20e]4484
4485                if (!root) {
4486                        syslog(LOG_ERR, "command create with no payload\n");
[9b708e0]4487                        err = og_client_bad_request(cli);
4488                        goto err_process_rest_payload;
[04ca20e]4489                }
4490                err = og_cmd_create_image(root, &params);
4491        } else if (!strncmp(cmd, "image/restore", strlen("image/restore"))) {
[9b708e0]4492                if (method != OG_METHOD_POST) {
4493                        err = og_client_method_not_found(cli);
4494                        goto err_process_rest_payload;
4495                }
[04ca20e]4496
4497                if (!root) {
4498                        syslog(LOG_ERR, "command create with no payload\n");
[9b708e0]4499                        err = og_client_bad_request(cli);
4500                        goto err_process_rest_payload;
[04ca20e]4501                }
4502                err = og_cmd_restore_image(root, &params);
4503        } else if (!strncmp(cmd, "setup", strlen("setup"))) {
[9b708e0]4504                if (method != OG_METHOD_POST) {
4505                        err = og_client_method_not_found(cli);
4506                        goto err_process_rest_payload;
4507                }
[04ca20e]4508
4509                if (!root) {
4510                        syslog(LOG_ERR, "command create with no payload\n");
[9b708e0]4511                        err = og_client_bad_request(cli);
4512                        goto err_process_rest_payload;
[04ca20e]4513                }
4514                err = og_cmd_setup(root, &params);
4515        } else if (!strncmp(cmd, "run/schedule", strlen("run/schedule"))) {
[9b708e0]4516                if (method != OG_METHOD_POST) {
4517                        err = og_client_method_not_found(cli);
4518                        goto err_process_rest_payload;
4519                }
[04ca20e]4520
4521                if (!root) {
4522                        syslog(LOG_ERR, "command create with no payload\n");
[9b708e0]4523                        err = og_client_bad_request(cli);
4524                        goto err_process_rest_payload;
[04ca20e]4525                }
4526
4527                err = og_cmd_run_schedule(root, &params);
4528        } else if (!strncmp(cmd, "task/run", strlen("task/run"))) {
[9b708e0]4529                if (method != OG_METHOD_POST) {
4530                        err = og_client_method_not_found(cli);
4531                        goto err_process_rest_payload;
4532                }
[04ca20e]4533
4534                if (!root) {
4535                        syslog(LOG_ERR, "command task with no payload\n");
[9b708e0]4536                        err = og_client_bad_request(cli);
4537                        goto err_process_rest_payload;
[04ca20e]4538                }
4539                err = og_cmd_task_post(root, &params);
4540        } else if (!strncmp(cmd, "schedule/create",
4541                            strlen("schedule/create"))) {
[9b708e0]4542                if (method != OG_METHOD_POST) {
4543                        err = og_client_method_not_found(cli);
4544                        goto err_process_rest_payload;
4545                }
[04ca20e]4546
4547                if (!root) {
4548                        syslog(LOG_ERR, "command task with no payload\n");
[9b708e0]4549                        err = og_client_bad_request(cli);
4550                        goto err_process_rest_payload;
[04ca20e]4551                }
4552                err = og_cmd_schedule_create(root, &params);
4553        } else if (!strncmp(cmd, "schedule/delete",
4554                            strlen("schedule/delete"))) {
[9b708e0]4555                if (method != OG_METHOD_POST) {
4556                        err = og_client_method_not_found(cli);
4557                        goto err_process_rest_payload;
4558                }
[04ca20e]4559
4560                if (!root) {
4561                        syslog(LOG_ERR, "command task with no payload\n");
[9b708e0]4562                        err = og_client_bad_request(cli);
4563                        goto err_process_rest_payload;
[04ca20e]4564                }
4565                err = og_cmd_schedule_delete(root, &params);
4566        } else if (!strncmp(cmd, "schedule/update",
4567                            strlen("schedule/update"))) {
[9b708e0]4568                if (method != OG_METHOD_POST) {
4569                        err = og_client_method_not_found(cli);
4570                        goto err_process_rest_payload;
4571                }
[04ca20e]4572
4573                if (!root) {
4574                        syslog(LOG_ERR, "command task with no payload\n");
[9b708e0]4575                        err = og_client_bad_request(cli);
4576                        goto err_process_rest_payload;
[04ca20e]4577                }
4578                err = og_cmd_schedule_update(root, &params);
4579        } else if (!strncmp(cmd, "schedule/get",
4580                            strlen("schedule/get"))) {
[9b708e0]4581                if (method != OG_METHOD_POST) {
4582                        err = og_client_method_not_found(cli);
4583                        goto err_process_rest_payload;
4584                }
[04ca20e]4585
4586                err = og_cmd_schedule_get(root, &params, buf_reply);
[8015f85]4587        } else if (!strncmp(cmd, "oglive/list",
4588                            strlen("oglive/list"))) {
4589                if (method != OG_METHOD_GET) {
4590                        err = og_client_method_not_found(cli);
4591                        goto err_process_rest_payload;
4592                }
4593
4594                err = og_cmd_oglive_list(buf_reply);
[0212091]4595        } else if (!strncmp(cmd, "center/add",
4596                            strlen("center/add"))) {
4597                if (method != OG_METHOD_POST) {
4598                        err = og_client_method_not_found(cli);
4599                        goto err_process_rest_payload;
4600                }
4601
4602                err = og_cmd_post_center_add(root, &params, buf_reply);
[29e7641]4603        } else if (!strncmp(cmd, "room/add",
4604                            strlen("room/add"))) {
4605                if (method != OG_METHOD_POST) {
4606                        err = og_client_method_not_found(cli);
4607                        goto err_process_rest_payload;
4608                }
4609
4610                if (!root) {
4611                        syslog(LOG_ERR, "command task with no payload\n");
4612                        err = og_client_bad_request(cli);
4613                        goto err_process_rest_payload;
4614                }
4615                err = og_cmd_post_room_add(root, &params);
[04ca20e]4616        } else {
4617                syslog(LOG_ERR, "unknown command: %.32s ...\n", cmd);
4618                err = og_client_not_found(cli);
4619        }
4620
[9b708e0]4621        json_decref(root);
[04ca20e]4622
4623        if (err < 0)
4624                return og_client_bad_request(cli);
4625
[90eab86]4626        return og_client_ok(cli, buf_reply);
[9b708e0]4627
4628err_process_rest_payload:
4629        json_decref(root);
4630
4631        return err;
[04ca20e]4632}
Note: See TracBrowser for help on using the repository browser.