source: ogServer-Git/sources/ogAdmServer.cpp @ 6c91d14

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

#915 Rename POST /image/setup for /setup in REST API

This patch renames the setup command to avoid semantic confusion.

  • Property mode set to 100644
File size: 158.1 KB
RevLine 
[6fc28cd]1// *******************************************************************************************************
[b9eb98b]2// Servicio: ogAdmServer
3// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
4// Fecha Creación: Marzo-2010
5// Fecha Última modificación: Marzo-2010
6// Nombre del fichero: ogAdmServer.cpp
7// Descripción :Este fichero implementa el servicio de administración general del sistema
[6fc28cd]8// *******************************************************************************************************
[b9eb98b]9#include "ogAdmServer.h"
10#include "ogAdmLib.c"
[212280e]11#include <ev.h>
[ef6e3d2]12#include <syslog.h>
[2baf362]13#include <sys/ioctl.h>
14#include <ifaddrs.h>
[c6020f2]15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
[95e6520]18#include <jansson.h>
[2427e9d]19
20static char usuario[LONPRM]; // Usuario de acceso a la base de datos
21static char pasguor[LONPRM]; // Password del usuario
22static char datasource[LONPRM]; // Dirección IP del gestor de base de datos
23static char catalog[LONPRM]; // Nombre de la base de datos
[2baf362]24static char interface[LONPRM]; // Interface name
[fd30540]25static char auth_token[LONPRM]; // API token
[2427e9d]26
[b9eb98b]27//________________________________________________________________________________________________________
28//      Función: tomaConfiguracion
29//
30//      Descripción:
31//              Lee el fichero de configuración del servicio
32//      Parámetros:
33//              filecfg : Ruta completa al fichero de configuración
34//      Devuelve:
[9dea2d6]35//              true: Si el proceso es correcto
36//              false: En caso de ocurrir algún error
[b9eb98b]37//________________________________________________________________________________________________________
[59fb4d5]38static bool tomaConfiguracion(const char *filecfg)
39{
[20fa7b9]40        char buf[1024], *line;
41        char *key, *value;
42        FILE *fcfg;
[b9eb98b]43
44        if (filecfg == NULL || strlen(filecfg) == 0) {
[b56cbeb]45                syslog(LOG_ERR, "No configuration file has been specified\n");
[9dea2d6]46                return false;
[b9eb98b]47        }
48
49        fcfg = fopen(filecfg, "rt");
50        if (fcfg == NULL) {
[b56cbeb]51                syslog(LOG_ERR, "Cannot open configuration file `%s'\n",
52                       filecfg);
[9dea2d6]53                return false;
[b9eb98b]54        }
55
56        servidoradm[0] = (char) NULL; //inicializar variables globales
57
[20fa7b9]58        line = fgets(buf, sizeof(buf), fcfg);
59        while (line != NULL) {
60                const char *delim = "=";
61
62                line[strlen(line) - 1] = '\0';
63
64                key = strtok(line, delim);
65                value = strtok(NULL, delim);
66
67                if (!strcmp(StrToUpper(key), "SERVIDORADM"))
68                        snprintf(servidoradm, sizeof(servidoradm), "%s", value);
69                else if (!strcmp(StrToUpper(key), "PUERTO"))
70                        snprintf(puerto, sizeof(puerto), "%s", value);
71                else if (!strcmp(StrToUpper(key), "USUARIO"))
72                        snprintf(usuario, sizeof(usuario), "%s", value);
73                else if (!strcmp(StrToUpper(key), "PASSWORD"))
74                        snprintf(pasguor, sizeof(pasguor), "%s", value);
75                else if (!strcmp(StrToUpper(key), "DATASOURCE"))
76                        snprintf(datasource, sizeof(datasource), "%s", value);
77                else if (!strcmp(StrToUpper(key), "CATALOG"))
78                        snprintf(catalog, sizeof(catalog), "%s", value);
[2baf362]79                else if (!strcmp(StrToUpper(key), "INTERFACE"))
80                        snprintf(interface, sizeof(interface), "%s", value);
[fd30540]81                else if (!strcmp(StrToUpper(key), "APITOKEN"))
82                        snprintf(auth_token, sizeof(auth_token), "%s", value);
[20fa7b9]83
84                line = fgets(buf, sizeof(buf), fcfg);
[b9eb98b]85        }
[20fa7b9]86
[a927e14]87        fclose(fcfg);
88
[aff4cfd]89        if (!servidoradm[0]) {
[b56cbeb]90                syslog(LOG_ERR, "Missing SERVIDORADM in configuration file\n");
[9dea2d6]91                return false;
[b9eb98b]92        }
[aff4cfd]93        if (!puerto[0]) {
[b56cbeb]94                syslog(LOG_ERR, "Missing PUERTO in configuration file\n");
[9dea2d6]95                return false;
[b9eb98b]96        }
[aff4cfd]97        if (!usuario[0]) {
[b56cbeb]98                syslog(LOG_ERR, "Missing USUARIO in configuration file\n");
[9dea2d6]99                return false;
[b9eb98b]100        }
[aff4cfd]101        if (!pasguor[0]) {
[b56cbeb]102                syslog(LOG_ERR, "Missing PASSWORD in configuration file\n");
[9dea2d6]103                return false;
[b9eb98b]104        }
[aff4cfd]105        if (!datasource[0]) {
[b56cbeb]106                syslog(LOG_ERR, "Missing DATASOURCE in configuration file\n");
[9dea2d6]107                return false;
[b9eb98b]108        }
[aff4cfd]109        if (!catalog[0]) {
[b56cbeb]110                syslog(LOG_ERR, "Missing CATALOG in configuration file\n");
[9dea2d6]111                return false;
[b9eb98b]112        }
[2baf362]113        if (!interface[0])
114                syslog(LOG_ERR, "Missing INTERFACE in configuration file\n");
[eb99080]115
[9dea2d6]116        return true;
[b9eb98b]117}
[eb99080]118
[212280e]119enum og_client_state {
120        OG_CLIENT_RECEIVING_HEADER      = 0,
121        OG_CLIENT_RECEIVING_PAYLOAD,
122        OG_CLIENT_PROCESSING_REQUEST,
123};
124
[20dcb0a]125#define OG_MSG_REQUEST_MAXLEN   4096
126
[212280e]127/* Shut down connection if there is no complete message after 10 seconds. */
128#define OG_CLIENT_TIMEOUT       10
129
130struct og_client {
131        struct ev_io            io;
132        struct ev_timer         timer;
[ef6e3d2]133        struct sockaddr_in      addr;
[212280e]134        enum og_client_state    state;
[20dcb0a]135        char                    buf[OG_MSG_REQUEST_MAXLEN];
[212280e]136        unsigned int            buf_len;
137        unsigned int            msg_len;
[f09aca6]138        int                     keepalive_idx;
[95e6520]139        bool                    rest;
[36ad006]140        int                     content_length;
[fd30540]141        char                    auth_token[64];
[212280e]142};
143
144static inline int og_client_socket(const struct og_client *cli)
145{
146        return cli->io.fd;
147}
148
[b9eb98b]149// ________________________________________________________________________________________________________
150// Función: clienteDisponible
151//
152//      Descripción:
153//              Comprueba la disponibilidad del cliente para recibir comandos interactivos
154//      Parametros:
155//              - ip : La ip del cliente a buscar
156//              - idx: (Salida)  Indice que ocupa el cliente, de estar ya registrado
157//      Devuelve:
[9dea2d6]158//              true: Si el cliente está disponible
159//              false: En caso contrario
[b9eb98b]160// ________________________________________________________________________________________________________
[59fb4d5]161bool clienteDisponible(char *ip, int* idx)
162{
[b9eb98b]163        int estado;
164
165        if (clienteExistente(ip, idx)) {
166                estado = strcmp(tbsockets[*idx].estado, CLIENTE_OCUPADO); // Cliente ocupado
167                if (estado == 0)
[9dea2d6]168                        return false;
[b9eb98b]169
170                estado = strcmp(tbsockets[*idx].estado, CLIENTE_APAGADO); // Cliente apagado
171                if (estado == 0)
[9dea2d6]172                        return false;
[b9eb98b]173
174                estado = strcmp(tbsockets[*idx].estado, CLIENTE_INICIANDO); // Cliente en proceso de inclusión
175                if (estado == 0)
[9dea2d6]176                        return false;
[b9eb98b]177
[9dea2d6]178                return true; // En caso contrario el cliente está disponible
[b9eb98b]179        }
[9dea2d6]180        return false; // Cliente no está registrado en el sistema
[b9eb98b]181}
182// ________________________________________________________________________________________________________
183// Función: clienteExistente
184//
185//      Descripción:
186//              Comprueba si el cliente está registrado en la tabla de socket del sistema
187//      Parametros:
188//              - ip : La ip del cliente a buscar
189//              - idx:(Salida)  Indice que ocupa el cliente, de estar ya registrado
190//      Devuelve:
[9dea2d6]191//              true: Si el cliente está registrado
192//              false: En caso contrario
[b9eb98b]193// ________________________________________________________________________________________________________
[59fb4d5]194bool clienteExistente(char *ip, int* idx)
195{
[b9eb98b]196        int i;
197        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
198                if (contieneIP(ip, tbsockets[i].ip)) { // Si existe la IP en la cadena
199                        *idx = i;
[9dea2d6]200                        return true;
[b9eb98b]201                }
202        }
[9dea2d6]203        return false;
[b9eb98b]204}
205// ________________________________________________________________________________________________________
206// Función: hayHueco
207//
208//      Descripción:
[9dea2d6]209//              Esta función devuelve true o false dependiendo de que haya hueco en la tabla de sockets para un nuevo cliente.
[b9eb98b]210//      Parametros:
211//              - idx:   Primer indice libre que se podrn utilizar
212//      Devuelve:
[9dea2d6]213//              true: Si el proceso es correcto
214//              false: En caso de ocurrir algún error
[b9eb98b]215// ________________________________________________________________________________________________________
[59fb4d5]216static bool hayHueco(int *idx)
217{
[b9eb98b]218        int i;
219
220        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
221                if (strncmp(tbsockets[i].ip, "\0", 1) == 0) { // Hay un hueco
222                        *idx = i;
[9dea2d6]223                        return true;
[b9eb98b]224                }
225        }
[9dea2d6]226        return false;
[b9eb98b]227}
228// ________________________________________________________________________________________________________
[6fc28cd]229// Función: InclusionClienteWin
230//
231//      Descripción:
232//              Esta función incorpora el socket de un nuevo cliente Windows o Linux a la tabla de clientes
233//      Parámetros:
234//              - socket_c: Socket del cliente que envió el mensaje
235//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
236//      Devuelve:
[9dea2d6]237//              true: Si el proceso es correcto
238//              false: En caso de ocurrir algún error
[6fc28cd]239// ________________________________________________________________________________________________________
[212280e]240static bool InclusionClienteWinLnx(TRAMA *ptrTrama, struct og_client *cli)
[59fb4d5]241{
[212280e]242        int socket_c = og_client_socket(cli);
[6fc28cd]243        int res,idordenador,lon;
244        char nombreordenador[LONFIL];
[212280e]245
246        res = procesoInclusionClienteWinLnx(socket_c, ptrTrama, &idordenador,
247                                            nombreordenador);
248
[6fc28cd]249        // Prepara la trama de respuesta
250
251        initParametros(ptrTrama,0);
252        ptrTrama->tipo=MSG_RESPUESTA;
253        lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_InclusionClienteWinLnx\r");
254        lon += sprintf(ptrTrama->parametros + lon, "ido=%d\r", idordenador);
255        lon += sprintf(ptrTrama->parametros + lon, "npc=%s\r", nombreordenador);       
256        lon += sprintf(ptrTrama->parametros + lon, "res=%d\r", res);   
[b56cbeb]257
[07d2b73]258        if (!mandaTrama(&socket_c, ptrTrama)) {
[b56cbeb]259                syslog(LOG_ERR, "failed to send response to %s:%hu reason=%s\n",
260                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
261                       strerror(errno));
[9dea2d6]262                return false;
[6fc28cd]263        }
[9dea2d6]264        return true;
[6fc28cd]265}
266// ________________________________________________________________________________________________________
267// Función: procesoInclusionClienteWinLnx
268//
269//      Descripción:
270//              Implementa el proceso de inclusión en el sistema del Cliente Windows o Linux
271//      Parámetros de entrada:
272//              - socket_c: Socket del cliente que envió el mensaje
273//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
274//      Parámetros de salida:
275//              - ido: Identificador del ordenador
276//              - nombreordenador: Nombre del ordenador
277//      Devuelve:
278//              Código del error producido en caso de ocurrir algún error, 0 si el proceso es correcto
279// ________________________________________________________________________________________________________
[59fb4d5]280bool procesoInclusionClienteWinLnx(int socket_c, TRAMA *ptrTrama, int *idordenador, char *nombreordenador)
[6fc28cd]281 {
282        char msglog[LONSTD], sqlstr[LONSQL];
283        Database db;
284        Table tbl;
285        char *iph;
[9764185]286
[6fc28cd]287        // Toma parámetros
288        iph = copiaParametro("iph",ptrTrama); // Toma ip
289
[b56cbeb]290        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[466106d]291                liberaMemoria(iph);
[6fc28cd]292                db.GetErrorErrStr(msglog);
[b56cbeb]293                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
294                       __func__, __LINE__, msglog);
[162d780]295                return false;
[6fc28cd]296        }
297
298        // Recupera los datos del cliente
299        sprintf(sqlstr,
300                        "SELECT idordenador,nombreordenador FROM ordenadores "
301                                " WHERE ordenadores.ip = '%s'", iph);
302
[b56cbeb]303        if (!db.Execute(sqlstr, tbl)) {
[466106d]304                liberaMemoria(iph);
[6fc28cd]305                db.GetErrorErrStr(msglog);
[b56cbeb]306                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
307                       __func__, __LINE__, msglog);
[466106d]308                db.Close();
[162d780]309                return false;
[6fc28cd]310        }
311
[b56cbeb]312        if (tbl.ISEOF()) {
[466106d]313                liberaMemoria(iph);
[b56cbeb]314                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
315                       __func__, __LINE__);
[466106d]316                db.liberaResult(tbl);
317                db.Close();
[162d780]318                return false;
[6fc28cd]319        }
320
[b56cbeb]321        syslog(LOG_DEBUG, "Client %s requesting inclusion\n", iph);
322
[6fc28cd]323        if (!tbl.Get("idordenador", *idordenador)) {
[466106d]324                liberaMemoria(iph);
325                db.liberaResult(tbl);
[6fc28cd]326                tbl.GetErrorErrStr(msglog);
[9764185]327                og_info(msglog);
[466106d]328                db.Close();
[9dea2d6]329                return false;
[6fc28cd]330        }
331        if (!tbl.Get("nombreordenador", nombreordenador)) {
[466106d]332                liberaMemoria(iph);
333                db.liberaResult(tbl);
[6fc28cd]334                tbl.GetErrorErrStr(msglog);
[9764185]335                og_info(msglog);
[466106d]336                db.Close();
[9dea2d6]337                return false;
[6fc28cd]338        }
[466106d]339        db.liberaResult(tbl);
[6fc28cd]340        db.Close();
[162d780]341
[6fc28cd]342        if (!registraCliente(iph)) { // Incluyendo al cliente en la tabla de sokets
[eb99080]343                liberaMemoria(iph);
[b56cbeb]344                syslog(LOG_ERR, "client table is full\n");
[162d780]345                return false;
[6fc28cd]346        }
[eb99080]347        liberaMemoria(iph);
[162d780]348        return true;
[6fc28cd]349}
350// ________________________________________________________________________________________________________
[b9eb98b]351// Función: InclusionCliente
352//
353//      Descripción:
354//              Esta función incorpora el socket de un nuevo cliente a la tabla de clientes y le devuelve alguna de sus propiedades:
355//              nombre, identificador, tamaño de la caché , etc ...
356//      Parámetros:
357//              - socket_c: Socket del cliente que envió el mensaje
358//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
359//      Devuelve:
[9dea2d6]360//              true: Si el proceso es correcto
361//              false: En caso de ocurrir algún error
[b9eb98b]362// ________________________________________________________________________________________________________
[212280e]363static bool InclusionCliente(TRAMA *ptrTrama, struct og_client *cli)
[59fb4d5]364{
[212280e]365        int socket_c = og_client_socket(cli);
366
[b56cbeb]367        if (!procesoInclusionCliente(cli, ptrTrama)) {
[b9eb98b]368                initParametros(ptrTrama,0);
369                strcpy(ptrTrama->parametros, "nfn=RESPUESTA_InclusionCliente\rres=0\r");
[07d2b73]370                if (!mandaTrama(&socket_c, ptrTrama)) {
[b56cbeb]371                        syslog(LOG_ERR, "failed to send response to %s:%hu reason=%s\n",
372                               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
373                               strerror(errno));
[9dea2d6]374                        return false;
[b9eb98b]375                }
376        }
[9dea2d6]377        return true;
[59fb4d5]378}
[b9eb98b]379// ________________________________________________________________________________________________________
380// Función: procesoInclusionCliente
381//
382//      Descripción:
383//              Implementa el proceso de inclusión en el sistema del Cliente
384//      Parámetros:
385//              - socket_c: Socket del cliente que envió el mensaje
386//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
387//      Devuelve:
[9dea2d6]388//              true: Si el proceso es correcto
389//              false: En caso de ocurrir algún error
[b9eb98b]390// ________________________________________________________________________________________________________
[b56cbeb]391bool procesoInclusionCliente(struct og_client *cli, TRAMA *ptrTrama)
[59fb4d5]392{
[b56cbeb]393        int socket_c = og_client_socket(cli);
[b9eb98b]394        char msglog[LONSTD], sqlstr[LONSQL];
395        Database db;
396        Table tbl;
397
398        char *iph, *cfg;
399        char nombreordenador[LONFIL];
400        int lon, resul, idordenador, idmenu, cache, idproautoexec, idaula, idcentro;
401
402        // Toma parámetros
403        iph = copiaParametro("iph",ptrTrama); // Toma ip
404        cfg = copiaParametro("cfg",ptrTrama); // Toma configuracion
405
[b56cbeb]406        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[466106d]407                liberaMemoria(iph);
408                liberaMemoria(cfg);
[b9eb98b]409                db.GetErrorErrStr(msglog);
[b56cbeb]410                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
411                       __func__, __LINE__, msglog);
[9dea2d6]412                return false;
[b9eb98b]413        }
414
415        // Recupera los datos del cliente
416        sprintf(sqlstr,
417                        "SELECT ordenadores.*,aulas.idaula,centros.idcentro FROM ordenadores "
418                                " INNER JOIN aulas ON aulas.idaula=ordenadores.idaula"
419                                " INNER JOIN centros ON centros.idcentro=aulas.idcentro"
420                                " WHERE ordenadores.ip = '%s'", iph);
421
[b56cbeb]422        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]423                db.GetErrorErrStr(msglog);
[b56cbeb]424                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
425                       __func__, __LINE__, msglog);
[9dea2d6]426                return false;
[b9eb98b]427        }
428
[b56cbeb]429        if (tbl.ISEOF()) {
430                syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
431                       __func__, __LINE__);
[9dea2d6]432                return false;
[b9eb98b]433        }
434
[b56cbeb]435        syslog(LOG_DEBUG, "Client %s requesting inclusion\n", iph);
436
[b9eb98b]437        if (!tbl.Get("idordenador", idordenador)) {
438                tbl.GetErrorErrStr(msglog);
[9764185]439                og_info(msglog);
[9dea2d6]440                return false;
[b9eb98b]441        }
442        if (!tbl.Get("nombreordenador", nombreordenador)) {
443                tbl.GetErrorErrStr(msglog);
[9764185]444                og_info(msglog);
[9dea2d6]445                return false;
[b9eb98b]446        }
447        if (!tbl.Get("idmenu", idmenu)) {
448                tbl.GetErrorErrStr(msglog);
[9764185]449                og_info(msglog);
[9dea2d6]450                return false;
[b9eb98b]451        }
452        if (!tbl.Get("cache", cache)) {
453                tbl.GetErrorErrStr(msglog);
[9764185]454                og_info(msglog);
[9dea2d6]455                return false;
[b9eb98b]456        }
457        if (!tbl.Get("idproautoexec", idproautoexec)) {
458                tbl.GetErrorErrStr(msglog);
[9764185]459                og_info(msglog);
[9dea2d6]460                return false;
[b9eb98b]461        }
462        if (!tbl.Get("idaula", idaula)) {
463                tbl.GetErrorErrStr(msglog);
[9764185]464                og_info(msglog);
[9dea2d6]465                return false;
[b9eb98b]466        }
467        if (!tbl.Get("idcentro", idcentro)) {
468                tbl.GetErrorErrStr(msglog);
[9764185]469                og_info(msglog);
[9dea2d6]470                return false;
[b9eb98b]471        }
472
473        resul = actualizaConfiguracion(db, tbl, cfg, idordenador); // Actualiza la configuración del ordenador
[eb99080]474        liberaMemoria(cfg);
[b9eb98b]475        db.Close();
476
477        if (!resul) {
[eb99080]478                liberaMemoria(iph);
[b56cbeb]479                syslog(LOG_ERR, "Cannot add client to database\n");
[9dea2d6]480                return false;
[b9eb98b]481        }
482
483        if (!registraCliente(iph)) { // Incluyendo al cliente en la tabla de sokets
[eb99080]484                liberaMemoria(iph);
[b56cbeb]485                syslog(LOG_ERR, "client table is full\n");
[9dea2d6]486                return false;
[b9eb98b]487        }
488
489        /*------------------------------------------------------------------------------------------------------------------------------
490         Prepara la trama de respuesta
491         -------------------------------------------------------------------------------------------------------------------------------*/
492        initParametros(ptrTrama,0);
493        ptrTrama->tipo=MSG_RESPUESTA;
494        lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_InclusionCliente\r");
495        lon += sprintf(ptrTrama->parametros + lon, "ido=%d\r", idordenador);
496        lon += sprintf(ptrTrama->parametros + lon, "npc=%s\r", nombreordenador);
497        lon += sprintf(ptrTrama->parametros + lon, "che=%d\r", cache);
498        lon += sprintf(ptrTrama->parametros + lon, "exe=%d\r", idproautoexec);
499        lon += sprintf(ptrTrama->parametros + lon, "ida=%d\r", idaula);
500        lon += sprintf(ptrTrama->parametros + lon, "idc=%d\r", idcentro);
501        lon += sprintf(ptrTrama->parametros + lon, "res=%d\r", 1); // Confirmación proceso correcto
502
[07d2b73]503        if (!mandaTrama(&socket_c, ptrTrama)) {
[b56cbeb]504                syslog(LOG_ERR, "failed to send response to %s:%hu reason=%s\n",
505                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
506                       strerror(errno));
[9dea2d6]507                return false;
[b9eb98b]508        }
[eb99080]509        liberaMemoria(iph);
[9dea2d6]510        return true;
[b9eb98b]511}
512// ________________________________________________________________________________________________________
513// Función: actualizaConfiguracion
514//
515//      Descripción:
516//              Esta función actualiza la base de datos con la configuracion de particiones de un cliente
517//      Parámetros:
518//              - db: Objeto base de datos (ya operativo)
519//              - tbl: Objeto tabla
520//              - cfg: cadena con una Configuración
521//              - ido: Identificador del ordenador cliente
522//      Devuelve:
[9dea2d6]523//              true: Si el proceso es correcto
524//              false: En caso de ocurrir algún error
[b9eb98b]525//      Especificaciones:
526//              Los parametros de la configuración son:
527//                      par= Número de partición
528//                      cpt= Codigo o tipo de partición
529//                      sfi= Sistema de ficheros que está implementado en la partición
530//                      soi= Nombre del sistema de ficheros instalado en la partición
531//                      tam= Tamaño de la partición
532// ________________________________________________________________________________________________________
[59fb4d5]533bool actualizaConfiguracion(Database db, Table tbl, char *cfg, int ido)
[b9eb98b]534{
535        char msglog[LONSTD], sqlstr[LONSQL];
[827bac5]536        int lon, p, c,i, dato, swu, idsoi, idsfi,k;
[3de93a9]537        char *ptrPar[MAXPAR], *ptrCfg[7], *ptrDual[2], tbPar[LONSTD];
[24df599]538        char *ser, *disk, *par, *cpt, *sfi, *soi, *tam, *uso; // Parametros de configuración.
[b9eb98b]539
[9a2dc88]540        lon = 0;
[b9eb98b]541        p = splitCadena(ptrPar, cfg, '\n');
542        for (i = 0; i < p; i++) {
543                c = splitCadena(ptrCfg, ptrPar[i], '\t');
[24df599]544
545                // Si la 1ª línea solo incluye el número de serie del equipo; actualizar BD.
546                if (i == 0 && c == 1) {
547                        splitCadena(ptrDual, ptrCfg[0], '=');
548                        ser = ptrDual[1];
549                        if (strlen(ser) > 0) {
550                                // Solo actualizar si número de serie no existía.
551                                sprintf(sqlstr, "UPDATE ordenadores SET numserie='%s'"
[b502279]552                                                " WHERE idordenador=%d AND numserie IS NULL",
[24df599]553                                                ser, ido);
554                                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
555                                        db.GetErrorErrStr(msglog);
[9764185]556                                        og_info(msglog);
[9dea2d6]557                                        return false;
[24df599]558                                }
559                        }
560                        continue;
561                }
562
563                // Distribución de particionado.
[c4b75b1]564                disk = par = cpt = sfi = soi = tam = uso = NULL;
[24df599]565
[b9eb98b]566                splitCadena(ptrDual, ptrCfg[0], '=');
[99f74d8]567                disk = ptrDual[1]; // Número de disco
[b9eb98b]568
569                splitCadena(ptrDual, ptrCfg[1], '=');
[99f74d8]570                par = ptrDual[1]; // Número de partición
571
[d1e9613]572                k=splitCadena(ptrDual, ptrCfg[2], '=');
573                if(k==2){
574                        cpt = ptrDual[1]; // Código de partición
575                }else{
[24df599]576                        cpt = (char*)"0";
[d1e9613]577                }
[b9eb98b]578
[99f74d8]579                k=splitCadena(ptrDual, ptrCfg[3], '=');
[b9eb98b]580                if(k==2){
581                        sfi = ptrDual[1]; // Sistema de ficheros
[eb99080]582                        /* Comprueba existencia del s0xistema de ficheros instalado */
[b9eb98b]583                        idsfi = checkDato(db, tbl, sfi, "sistemasficheros", "descripcion","idsistemafichero");
584                }
585                else
586                        idsfi=0;
587
[99f74d8]588                k=splitCadena(ptrDual, ptrCfg[4], '=');
[b9eb98b]589                if(k==2){ // Sistema operativo detecdtado
590                        soi = ptrDual[1]; // Nombre del S.O. instalado
591                        /* Comprueba existencia del sistema operativo instalado */
592                        idsoi = checkDato(db, tbl, soi, "nombresos", "nombreso", "idnombreso");
593                }
594                else
595                        idsoi=0;
596
[99f74d8]597                splitCadena(ptrDual, ptrCfg[5], '=');
[b9eb98b]598                tam = ptrDual[1]; // Tamaño de la partición
599
[c4b75b1]600                splitCadena(ptrDual, ptrCfg[6], '=');
601                uso = ptrDual[1]; // Porcentaje de uso del S.F.
602
[9a2dc88]603                lon += sprintf(tbPar + lon, "(%s, %s),", disk, par);
[b9eb98b]604
[1845104]605                sprintf(sqlstr, "SELECT numdisk, numpar, tamano, uso, idsistemafichero, idnombreso"
[c4b75b1]606                                "  FROM ordenadores_particiones"
607                                " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
[99f74d8]608                                ido, disk, par);
[e1ca941]609
610
[b56cbeb]611                if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]612                        db.GetErrorErrStr(msglog);
[b56cbeb]613                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
614                               __func__, __LINE__, msglog);
[9dea2d6]615                        return false;
[b9eb98b]616                }
617                if (tbl.ISEOF()) { // Si no existe el registro
[c4b75b1]618                        sprintf(sqlstr, "INSERT INTO ordenadores_particiones(idordenador,numdisk,numpar,codpar,tamano,uso,idsistemafichero,idnombreso,idimagen)"
619                                        " VALUES(%d,%s,%s,0x%s,%s,%s,%d,%d,0)",
620                                        ido, disk, par, cpt, tam, uso, idsfi, idsoi);
[e1ca941]621
622
[b9eb98b]623                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
624                                db.GetErrorErrStr(msglog);
[9764185]625                                og_info(msglog);
[9dea2d6]626                                return false;
[b9eb98b]627                        }
628                } else { // Existe el registro
[9dea2d6]629                        swu = true; // Se supone que algún dato ha cambiado
[1845104]630                        if (!tbl.Get("tamano", dato)) { // Toma dato
[b9eb98b]631                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]632                                og_info(msglog);
[9dea2d6]633                                return false;
[b9eb98b]634                        }
[1845104]635                        if (atoi(tam) == dato) { // Parámetro tamaño igual al almacenado
636                                if (!tbl.Get("idsistemafichero", dato)) { // Toma dato
[b9eb98b]637                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]638                                        og_info(msglog);
[9dea2d6]639                                        return false;
[b9eb98b]640                                }
[1845104]641                                if (idsfi == dato) { // Parámetro sistema de fichero igual al almacenado
642                                        if (!tbl.Get("idnombreso", dato)) { // Toma dato
[b9eb98b]643                                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]644                                                og_info(msglog);
[9dea2d6]645                                                return false;
[b9eb98b]646                                        }
[1845104]647                                        if (idsoi == dato) { // Parámetro sistema operativo distinto al almacenado
648                                                swu = false; // Todos los parámetros de la partición son iguales, no se actualiza
[b9eb98b]649                                        }
650                                }
651                        }
652                        if (swu) { // Hay que actualizar los parámetros de la partición
653                                sprintf(sqlstr, "UPDATE ordenadores_particiones SET "
654                                        " codpar=0x%s,"
655                                        " tamano=%s,"
[c4b75b1]656                                        " uso=%s,"
[b9eb98b]657                                        " idsistemafichero=%d,"
658                                        " idnombreso=%d,"
[599c505]659                                        " idimagen=0,"
660                                        " idperfilsoft=0,"
661                                        " fechadespliegue=NULL"
[99f74d8]662                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
[c4b75b1]663                                        cpt, tam, uso, idsfi, idsoi, ido, disk, par);
[d56675d]664                        } else {  // Actualizar porcentaje de uso.
665                                sprintf(sqlstr, "UPDATE ordenadores_particiones SET "
666                                        " uso=%s"
667                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
668                                        uso, ido, disk, par);
669                        }
[b56cbeb]670                        if (!db.Execute(sqlstr, tbl)) {
[d56675d]671                                db.GetErrorErrStr(msglog);
[b56cbeb]672                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
673                                       __func__, __LINE__, msglog);
[9dea2d6]674                                return false;
[b9eb98b]675                        }
676                }
677        }
[9a2dc88]678        lon += sprintf(tbPar + lon, "(0,0)");
[b9eb98b]679        // Eliminar particiones almacenadas que ya no existen
[9a2dc88]680        sprintf(sqlstr, "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)",
681                        ido, tbPar);
[b56cbeb]682        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]683                db.GetErrorErrStr(msglog);
[b56cbeb]684                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
685                       __func__, __LINE__, msglog);
[9dea2d6]686                return false;
[b9eb98b]687        }
[9dea2d6]688        return true;
[b9eb98b]689}
690// ________________________________________________________________________________________________________
691// Función: checkDato
692//
693//      Descripción:
694//               Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en
695//              cualquier caso el identificador del registro existenet o del insertado
696//      Parámetros:
697//              - db: Objeto base de datos (ya operativo)
698//              - tbl: Objeto tabla
699//              - dato: Dato
700//              - tabla: Nombre de la tabla
701//              - nomdato: Nombre del dato en la tabla
702//              - nomidentificador: Nombre del identificador en la tabla
703//      Devuelve:
704//              El identificador del registro existente o el del insertado
705//
706//      Especificaciones:
707//              En caso de producirse algún error se devuelve el valor 0
708// ________________________________________________________________________________________________________
709
[59fb4d5]710int checkDato(Database db, Table tbl, char *dato, const char *tabla,
711                     const char *nomdato, const char *nomidentificador)
712{
[b9eb98b]713        char msglog[LONSTD], sqlstr[LONSQL];
714        int identificador;
715
716        if (strlen(dato) == 0)
717                return (0); // EL dato no tiene valor
718        sprintf(sqlstr, "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador,
719                        tabla, nomdato, dato);
720
721        // Ejecuta consulta
[b56cbeb]722        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]723                db.GetErrorErrStr(msglog);
[b56cbeb]724                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
725                       __func__, __LINE__, msglog);
[b9eb98b]726                return (0);
727        }
728        if (tbl.ISEOF()) { //  Software NO existente
[bde1389]729                sprintf(sqlstr, "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato);
[b9eb98b]730                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
731                        db.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]732                        og_info(msglog);
[b9eb98b]733                        return (0);
734                }
735                // Recupera el identificador del software
736                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
737                if (!db.Execute(sqlstr, tbl)) { // Error al leer
738                        db.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]739                        og_info(msglog);
[b9eb98b]740                        return (0);
741                }
742                if (!tbl.ISEOF()) { // Si existe registro
743                        if (!tbl.Get("identificador", identificador)) {
744                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]745                                og_info(msglog);
[b9eb98b]746                                return (0);
747                        }
748                }
749        } else {
750                if (!tbl.Get(nomidentificador, identificador)) { // Toma dato
751                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]752                        og_info(msglog);
[b9eb98b]753                        return (0);
754                }
755        }
756        return (identificador);
757}
758// ________________________________________________________________________________________________________
759// Función: registraCliente
760//
761//      Descripción:
762//               Incluye al cliente en la tabla de sokets
763//      Parámetros:
764//              - iph: Dirección ip del cliente
765//      Devuelve:
[9dea2d6]766//              true: Si el proceso es correcto
767//              false: En caso de ocurrir algún error
[b9eb98b]768// ________________________________________________________________________________________________________
[59fb4d5]769bool registraCliente(char *iph)
770{
[b9eb98b]771        int idx;
772
773        if (!clienteExistente(iph, &idx)) { // Si no existe la IP ...
774                if (!hayHueco(&idx)) { // Busca hueco para el nuevo cliente
[9dea2d6]775                        return false; // No hay huecos
[b9eb98b]776                }
777        }
778        strcpy(tbsockets[idx].ip, iph); // Copia IP
779        strcpy(tbsockets[idx].estado, CLIENTE_INICIANDO); // Actualiza el estado del cliente
[9dea2d6]780        return true;
[b9eb98b]781}
782// ________________________________________________________________________________________________________
783// Función: AutoexecCliente
784//
785//      Descripción:
786//              Envía archivo de autoexec al cliente
787//      Parámetros:
788//              - socket_c: Socket del cliente que envió el mensaje
789//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
790//      Devuelve:
[9dea2d6]791//              true: Si el proceso es correcto
792//              false: En caso de ocurrir algún error
[b9eb98b]793// ________________________________________________________________________________________________________
[212280e]794static bool AutoexecCliente(TRAMA *ptrTrama, struct og_client *cli)
[59fb4d5]795{
[212280e]796        int socket_c = og_client_socket(cli);
[b9eb98b]797        int lon;
798        char *iph, *exe, msglog[LONSTD];
799        Database db;
800        FILE *fileexe;
801        char fileautoexec[LONPRM];
802        char parametros[LONGITUD_PARAMETROS];
803
804        iph = copiaParametro("iph",ptrTrama); // Toma dirección IP del cliente
805        exe = copiaParametro("exe",ptrTrama); // Toma identificador del procedimiento inicial
806
807        sprintf(fileautoexec, "/tmp/Sautoexec-%s", iph);
[eb99080]808        liberaMemoria(iph);
[b9eb98b]809        fileexe = fopen(fileautoexec, "wb"); // Abre fichero de script
810        if (fileexe == NULL) {
[b56cbeb]811                syslog(LOG_ERR, "cannot create temporary file\n");
[9dea2d6]812                return false;
[b9eb98b]813        }
814
[b56cbeb]815        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]816                db.GetErrorErrStr(msglog);
[b56cbeb]817                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
818                       __func__, __LINE__, msglog);
[9dea2d6]819                return false;
[b9eb98b]820        }
821        initParametros(ptrTrama,0);
822        if (recorreProcedimientos(db, parametros, fileexe, exe)) {
823                lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_AutoexecCliente\r");
824                lon += sprintf(ptrTrama->parametros + lon, "nfl=%s\r", fileautoexec);
825                lon += sprintf(ptrTrama->parametros + lon, "res=1\r");
826        } else {
827                lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_AutoexecCliente\r");
828                lon += sprintf(ptrTrama->parametros + lon, "res=0\r");
829        }
830
[fcc271f]831        db.Close();
[b9eb98b]832        fclose(fileexe);
833
[07d2b73]834        if (!mandaTrama(&socket_c, ptrTrama)) {
[eb99080]835                liberaMemoria(exe);
[b56cbeb]836                syslog(LOG_ERR, "failed to send response to %s:%hu reason=%s\n",
837                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
838                       strerror(errno));
[9dea2d6]839                return false;
[b9eb98b]840        }
[eb99080]841        liberaMemoria(exe);
[9dea2d6]842        return true;
[b9eb98b]843}
844// ________________________________________________________________________________________________________
845// Función: recorreProcedimientos
846//
847//      Descripción:
848//              Crea un archivo con el código de un procedimiento separando cada comando  por un salto de linea
849//      Parámetros:
850//              Database db,char* parametros,FILE* fileexe,char* idp
851//      Devuelve:
[9dea2d6]852//              true: Si el proceso es correcto
853//              false: En caso de ocurrir algún error
[b9eb98b]854// ________________________________________________________________________________________________________
[59fb4d5]855bool recorreProcedimientos(Database db, char *parametros, FILE *fileexe, char *idp)
856{
[b9eb98b]857        int procedimientoid, lsize;
858        char idprocedimiento[LONPRM], msglog[LONSTD], sqlstr[LONSQL];
859        Table tbl;
860
861        /* Busca procedimiento */
862        sprintf(sqlstr,
863                        "SELECT procedimientoid,parametros FROM procedimientos_acciones"
864                                " WHERE idprocedimiento=%s ORDER BY orden", idp);
865        // Ejecuta consulta
[b56cbeb]866        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]867                db.GetErrorErrStr(msglog);
[b56cbeb]868                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
869                       __func__, __LINE__, msglog);
[9dea2d6]870                return false;
[b9eb98b]871        }
872        while (!tbl.ISEOF()) { // Recorre procedimientos
873                if (!tbl.Get("procedimientoid", procedimientoid)) { // Toma dato
874                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]875                        og_info(msglog);
[9dea2d6]876                        return false;
[b9eb98b]877                }
878                if (procedimientoid > 0) { // Procedimiento recursivo
879                        sprintf(idprocedimiento, "%d", procedimientoid);
880                        if (!recorreProcedimientos(db, parametros, fileexe, idprocedimiento)) {
[9dea2d6]881                                return false;
[b9eb98b]882                        }
883                } else {
884                        if (!tbl.Get("parametros", parametros)) { // Toma dato
885                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]886                                og_info(msglog);
[9dea2d6]887                                return false;
[b9eb98b]888                        }
889                        strcat(parametros, "@");
890                        lsize = strlen(parametros);
891                        fwrite(parametros, 1, lsize, fileexe); // Escribe el código a ejecutar
892                }
893                tbl.MoveNext();
894        }
[9dea2d6]895        return true;
[b9eb98b]896}
897// ________________________________________________________________________________________________________
898// Función: ComandosPendientes
899//
900//      Descripción:
901//              Esta función busca en la base de datos,comandos pendientes de ejecutar por un  ordenador  concreto
902//      Parámetros:
903//              - socket_c: Socket del cliente que envió el mensaje
904//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
905//      Devuelve:
[9dea2d6]906//              true: Si el proceso es correcto
907//              false: En caso de ocurrir algún error
[b9eb98b]908// ________________________________________________________________________________________________________
[212280e]909static bool ComandosPendientes(TRAMA *ptrTrama, struct og_client *cli)
[eb99080]910{
[212280e]911        int socket_c = og_client_socket(cli);
[eb99080]912        char *ido,*iph,pids[LONPRM];
[b9eb98b]913        int ids, idx;
914
[eb99080]915        iph = copiaParametro("iph",ptrTrama); // Toma dirección IP
[b9eb98b]916        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
917
918        if (!clienteExistente(iph, &idx)) { // Busca índice del cliente
[eb99080]919                liberaMemoria(iph);
920                liberaMemoria(ido);
[b56cbeb]921                syslog(LOG_ERR, "client does not exist\n");
[9dea2d6]922                return false;
[b9eb98b]923        }
924        if (buscaComandos(ido, ptrTrama, &ids)) { // Existen comandos pendientes
925                ptrTrama->tipo = MSG_COMANDO;
926                sprintf(pids, "\rids=%d\r", ids);
927                strcat(ptrTrama->parametros, pids);
928                strcpy(tbsockets[idx].estado, CLIENTE_OCUPADO);
929        } else {
930                initParametros(ptrTrama,0);
931                strcpy(ptrTrama->parametros, "nfn=NoComandosPtes\r");
932        }
[07d2b73]933        if (!mandaTrama(&socket_c, ptrTrama)) {
[eb99080]934                liberaMemoria(iph);
[b56cbeb]935                liberaMemoria(ido);
936                syslog(LOG_ERR, "failed to send response to %s:%hu reason=%s\n",
937                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
938                       strerror(errno));
[9dea2d6]939                return false;
[b9eb98b]940        }
[eb99080]941        liberaMemoria(iph);
942        liberaMemoria(ido);     
[9dea2d6]943        return true;
[b9eb98b]944}
945// ________________________________________________________________________________________________________
946// Función: buscaComandos
947//
948//      Descripción:
949//              Busca en la base de datos,comandos pendientes de ejecutar por el cliente
950//      Parámetros:
951//              - ido: Identificador del ordenador
952//              - cmd: Parámetros del comando (Salida)
[eb99080]953//              - ids: Identificador de la sesion(Salida)
[b9eb98b]954//      Devuelve:
[9dea2d6]955//              true: Si el proceso es correcto
956//              false: En caso de ocurrir algún error
[b9eb98b]957// ________________________________________________________________________________________________________
[f74067f]958bool buscaComandos(char *ido, TRAMA *ptrTrama, int *ids)
[b9eb98b]959{
960        char msglog[LONSTD], sqlstr[LONSQL];
961        Database db;
962        Table tbl;
963        int lonprm;
964
[b56cbeb]965        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]966                db.GetErrorErrStr(msglog);
[b56cbeb]967                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
968                       __func__, __LINE__, msglog);
[9dea2d6]969                return false;
[b9eb98b]970        }
[eb99080]971        sprintf(sqlstr,"SELECT sesion,parametros,length( parametros) as lonprm"\
[b9eb98b]972                        " FROM acciones WHERE idordenador=%s AND estado='%d' ORDER BY idaccion", ido, ACCION_INICIADA);
[b56cbeb]973        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]974                db.GetErrorErrStr(msglog);
[b56cbeb]975                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
976                       __func__, __LINE__, msglog);
[9dea2d6]977                return false;
[b9eb98b]978        }
979        if (tbl.ISEOF()) {
980                db.Close();
[9dea2d6]981                return false; // No hay comandos pendientes
[b9eb98b]982        } else { // Busca entre todas las acciones de diversos ambitos
[eb99080]983                if (!tbl.Get("sesion", *ids)) { // Toma identificador de la sesion
[b9eb98b]984                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]985                        og_info(msglog);
[9dea2d6]986                        return false;
[b9eb98b]987                }
988                if (!tbl.Get("lonprm", lonprm)) { // Toma parámetros del comando
989                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]990                        og_info(msglog);
[9dea2d6]991                        return false;
[b9eb98b]992                }
993                if(!initParametros(ptrTrama,lonprm+LONGITUD_PARAMETROS)){
994                        db.Close();
[b56cbeb]995                        syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]996                        return false;
[b9eb98b]997                }
998                if (!tbl.Get("parametros", ptrTrama->parametros)) { // Toma parámetros del comando
999                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]1000                        og_info(msglog);
[9dea2d6]1001                        return false;
[b9eb98b]1002                }
1003        }
1004        db.Close();
[9dea2d6]1005        return true; // Hay comandos pendientes, se toma el primero de la cola
[b9eb98b]1006}
1007// ________________________________________________________________________________________________________
1008// Función: DisponibilidadComandos
1009//
1010//      Descripción:
1011//              Esta función habilita a un cliente para recibir comandos desde la consola
1012//      Parámetros:
1013//              - socket_c: Socket del cliente que envió el mensaje
1014//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1015//      Devuelve:
[9dea2d6]1016//              true: Si el proceso es correcto
1017//              false: En caso de ocurrir algún error
[b9eb98b]1018// ________________________________________________________________________________________________________
[eb99080]1019//
[212280e]1020static bool DisponibilidadComandos(TRAMA *ptrTrama, struct og_client *cli)
[eb99080]1021{
1022        char *iph, *tpc;
[f09aca6]1023        int idx;
[b9eb98b]1024
[eb99080]1025        iph = copiaParametro("iph",ptrTrama); // Toma ip
[b9eb98b]1026        if (!clienteExistente(iph, &idx)) { // Busca índice del cliente
[eb99080]1027                liberaMemoria(iph);
[b56cbeb]1028                syslog(LOG_ERR, "client does not exist\n");
[9dea2d6]1029                return false;
[b9eb98b]1030        }
[eb99080]1031        tpc = copiaParametro("tpc",ptrTrama); // Tipo de cliente (Plataforma y S.O.)
[b9eb98b]1032        strcpy(tbsockets[idx].estado, tpc);
[f09aca6]1033        cli->keepalive_idx = idx;
[eb99080]1034        liberaMemoria(iph);
1035        liberaMemoria(tpc);             
[9dea2d6]1036        return true;
[b9eb98b]1037}
1038// ________________________________________________________________________________________________________
1039// Función: respuestaEstandar
1040//
1041//      Descripción:
1042//              Esta función actualiza la base de datos con el resultado de la ejecución de un comando con seguimiento
1043//      Parámetros:
1044//              - res: resultado de la ejecución del comando
1045//              - der: Descripción del error si hubiese habido
1046//              - iph: Dirección IP
[eb99080]1047//              - ids: identificador de la sesión
[b9eb98b]1048//              - ido: Identificador del ordenador que notifica
1049//              - db: Objeto base de datos (operativo)
1050//              - tbl: Objeto tabla
1051//      Devuelve:
[9dea2d6]1052//              true: Si el proceso es correcto
1053//              false: En caso de ocurrir algún error
[b9eb98b]1054// ________________________________________________________________________________________________________
[59fb4d5]1055static bool respuestaEstandar(TRAMA *ptrTrama, char *iph, char *ido, Database db,
1056                Table tbl)
1057{
[b9eb98b]1058        char msglog[LONSTD], sqlstr[LONSQL];
1059        char *res, *ids, *der;
1060        char fechafin[LONPRM];
1061        struct tm* st;
[eb99080]1062        int idaccion;
[b9eb98b]1063
[8082efd]1064        ids = copiaParametro("ids",ptrTrama);
1065        res = copiaParametro("res",ptrTrama);
[b9eb98b]1066
[8082efd]1067        if (ids == NULL) {
1068                if (atoi(res) == ACCION_FALLIDA) {
1069                        liberaMemoria(res);
1070                        return false;
1071                }
1072                liberaMemoria(res);
[9dea2d6]1073                return true;
[8082efd]1074        }
[9dea2d6]1075
[8082efd]1076        if (atoi(ids) == 0) {
[eb99080]1077                liberaMemoria(ids);
[8082efd]1078                if (atoi(res) == ACCION_FALLIDA) {
1079                        liberaMemoria(res);
1080                        return false;
1081                }
1082                liberaMemoria(res);
[9dea2d6]1083                return true;
[eb99080]1084        }
[b9eb98b]1085
1086        sprintf(sqlstr,
[eb99080]1087                        "SELECT * FROM acciones WHERE idordenador=%s"
1088                        " AND sesion=%s ORDER BY idaccion", ido,ids);
1089
1090        liberaMemoria(ids);
1091
[b56cbeb]1092        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]1093                db.GetErrorErrStr(msglog);
[b56cbeb]1094                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1095                       __func__, __LINE__, msglog);
[9dea2d6]1096                return false;
[b9eb98b]1097        }
[b56cbeb]1098        if (tbl.ISEOF()) {
1099                syslog(LOG_ERR, "no actions available\n");
[9dea2d6]1100                return true;
[b9eb98b]1101        }
[eb99080]1102        if (!tbl.Get("idaccion", idaccion)) { // Toma identificador de la accion
1103                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]1104                og_info(msglog);
[9dea2d6]1105                return false;
[eb99080]1106        }
[b9eb98b]1107        st = tomaHora();
1108        sprintf(fechafin, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon + 1,
1109                        st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
1110
[eb99080]1111        der = copiaParametro("der",ptrTrama); // Toma descripción del error (si hubiera habido)
1112       
[28cc16b]1113        sprintf(sqlstr,
1114                        "UPDATE acciones"\
1115                        "   SET resultado='%s',estado='%d',fechahorafin='%s',descrinotificacion='%s'"\
[eb99080]1116                        " WHERE idordenador=%s AND idaccion=%d",
1117                        res, ACCION_FINALIZADA, fechafin, der, ido, idaccion);
1118                       
[b9eb98b]1119        if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
[eb99080]1120                liberaMemoria(res);
1121                liberaMemoria(der);
[b9eb98b]1122                db.GetErrorErrStr(msglog);
[9764185]1123                og_info(msglog);
[9dea2d6]1124                return false;
[b9eb98b]1125        }
[eb99080]1126       
1127        liberaMemoria(der);
[b9eb98b]1128
[28cc16b]1129        liberaMemoria(res);
[9dea2d6]1130        return true;
[b9eb98b]1131}
[e979fd2]1132
1133static bool og_send_cmd(char *ips_array[], int ips_array_len,
1134                        const char *state, TRAMA *ptrTrama)
1135{
1136        int i, idx;
1137
1138        for (i = 0; i < ips_array_len; i++) {
1139                if (clienteDisponible(ips_array[i], &idx)) { // Si el cliente puede recibir comandos
1140                        int sock = tbsockets[idx].cli ? tbsockets[idx].cli->io.fd : -1;
1141
1142                        strcpy(tbsockets[idx].estado, state); // Actualiza el estado del cliente
[3e8fcf0]1143                        if (sock >= 0 && !mandaTrama(&sock, ptrTrama)) {
[e979fd2]1144                                syslog(LOG_ERR, "failed to send response to %s:%s\n",
1145                                       ips_array[i], strerror(errno));
1146                        }
1147                }
1148        }
1149        return true;
1150}
1151
[b9eb98b]1152// ________________________________________________________________________________________________________
1153// Función: enviaComando
1154//
1155//      Descripción:
1156//              Envía un comando a los clientes
1157//      Parámetros:
1158//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1159//              - estado: Estado en el se deja al cliente mientras se ejecuta el comando
1160//      Devuelve:
[9dea2d6]1161//              true: Si el proceso es correcto
1162//              false: En caso de ocurrir algún error
[b9eb98b]1163// ________________________________________________________________________________________________________
[f74067f]1164bool enviaComando(TRAMA* ptrTrama, const char *estado)
[59fb4d5]1165{
[b9eb98b]1166        char *iph, *Ipes, *ptrIpes[MAXIMOS_CLIENTES];
[e979fd2]1167        int lon;
[b9eb98b]1168
1169        iph = copiaParametro("iph",ptrTrama); // Toma dirección/es IP
1170        lon = strlen(iph); // Calcula longitud de la cadena de direccion/es IPE/S
1171        Ipes = (char*) reservaMemoria(lon + 1);
1172        if (Ipes == NULL) {
[b56cbeb]1173                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]1174                return false;
[b9eb98b]1175        }
[eb99080]1176       
[b9eb98b]1177        strcpy(Ipes, iph); // Copia cadena de IPES
[eb99080]1178        liberaMemoria(iph);
1179
[b9eb98b]1180        lon = splitCadena(ptrIpes, Ipes, ';');
1181        FINCADaINTRO(ptrTrama);
[f09aca6]1182
[e979fd2]1183        if (!og_send_cmd(ptrIpes, lon, estado, ptrTrama))
1184                return false;
1185
[7f46c45]1186        liberaMemoria(Ipes);
[9dea2d6]1187        return true;
[b9eb98b]1188}
1189//______________________________________________________________________________________________________
1190// Función: respuestaConsola
1191//
1192//      Descripción:
1193//              Envia una respuesta a la consola sobre el resultado de la ejecución de un comando
1194//      Parámetros:
1195//              - socket_c: (Salida) Socket utilizado para el envío
1196//              - res: Resultado del envío del comando
1197//      Devuelve:
[9dea2d6]1198//              true: Si el proceso es correcto
1199//              false: En caso de ocurrir algún error
[b9eb98b]1200// ________________________________________________________________________________________________________
[59fb4d5]1201bool respuestaConsola(int socket_c, TRAMA *ptrTrama, int res)
1202{
[b9eb98b]1203        initParametros(ptrTrama,0);
1204        sprintf(ptrTrama->parametros, "res=%d\r", res);
[07d2b73]1205        if (!mandaTrama(&socket_c, ptrTrama)) {
[b56cbeb]1206                syslog(LOG_ERR, "%s:%d failed to send response: %s\n",
1207                       __func__, __LINE__, strerror(errno));
[9dea2d6]1208                return false;
[b9eb98b]1209        }
[9dea2d6]1210        return true;
[b9eb98b]1211}
1212// ________________________________________________________________________________________________________
1213// Función: Levanta
1214//
1215//      Descripción:
1216//              Enciende ordenadores a través de la red cuyas macs se pasan como parámetro
1217//      Parámetros:
[0cee7a6]1218//              - iph: Cadena de direcciones ip separadas por ";"
[b9eb98b]1219//              - mac: Cadena de direcciones mac separadas por ";"
[0cee7a6]1220//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
[b9eb98b]1221//      Devuelve:
[9dea2d6]1222//              true: Si el proceso es correcto
1223//              false: En caso de ocurrir algún error
[b9eb98b]1224// ________________________________________________________________________________________________________
[507c75c]1225
1226bool Levanta(char *ptrIP[], char *ptrMacs[], int lon, char *mar)
[0cee7a6]1227{
[63a3d4d]1228        unsigned int on = 1;
1229        sockaddr_in local;
[507c75c]1230        int i, res;
[b38ed0d]1231        int s;
[b9eb98b]1232
1233        /* Creación de socket para envío de magig packet */
1234        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
[28b435c]1235        if (s < 0) {
[b56cbeb]1236                syslog(LOG_ERR, "cannot create socket for magic packet\n");
[9dea2d6]1237                return false;
[b9eb98b]1238        }
[63a3d4d]1239        res = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (unsigned int *) &on,
1240                         sizeof(on));
[28b435c]1241        if (res < 0) {
[b56cbeb]1242                syslog(LOG_ERR, "cannot set broadcast socket\n");
[9dea2d6]1243                return false;
[b9eb98b]1244        }
[63a3d4d]1245        memset(&local, 0, sizeof(local));
[b9eb98b]1246        local.sin_family = AF_INET;
[63a3d4d]1247        local.sin_port = htons(PUERTO_WAKEUP);
1248        local.sin_addr.s_addr = htonl(INADDR_ANY);
1249
[b9eb98b]1250        for (i = 0; i < lon; i++) {
[b38ed0d]1251                if (!WakeUp(s, ptrIP[i], ptrMacs[i], mar)) {
[b56cbeb]1252                        syslog(LOG_ERR, "problem sending magic packet\n");
[b9eb98b]1253                        close(s);
[9dea2d6]1254                        return false;
[b9eb98b]1255                }
1256        }
1257        close(s);
[9dea2d6]1258        return true;
[b9eb98b]1259}
[2baf362]1260
1261#define OG_WOL_SEQUENCE         6
1262#define OG_WOL_MACADDR_LEN      6
1263#define OG_WOL_REPEAT           16
1264
1265struct wol_msg {
1266        char secuencia_FF[OG_WOL_SEQUENCE];
1267        char macbin[OG_WOL_REPEAT][OG_WOL_MACADDR_LEN];
1268};
1269
1270static bool wake_up_broadcast(int sd, struct sockaddr_in *client,
1271                              const struct wol_msg *msg)
1272{
1273        struct sockaddr_in *broadcast_addr;
1274        struct ifaddrs *ifaddr, *ifa;
1275        int ret;
1276
1277        if (getifaddrs(&ifaddr) < 0) {
1278                syslog(LOG_ERR, "cannot get list of addresses\n");
1279                return false;
1280        }
1281
1282        client->sin_addr.s_addr = htonl(INADDR_BROADCAST);
1283
1284        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
1285                if (ifa->ifa_addr == NULL ||
1286                    ifa->ifa_addr->sa_family != AF_INET ||
1287                    strcmp(ifa->ifa_name, interface) != 0)
1288                        continue;
1289
1290                broadcast_addr =
1291                        (struct sockaddr_in *)ifa->ifa_ifu.ifu_broadaddr;
1292                client->sin_addr.s_addr = broadcast_addr->sin_addr.s_addr;
1293                break;
1294        }
[8322fd6]1295        freeifaddrs(ifaddr);
[2baf362]1296
1297        ret = sendto(sd, msg, sizeof(*msg), 0,
1298                     (sockaddr *)client, sizeof(*client));
1299        if (ret < 0) {
1300                syslog(LOG_ERR, "failed to send broadcast wol\n");
1301                return false;
1302        }
1303
1304        return true;
1305}
1306
1307static bool wake_up_unicast(int sd, struct sockaddr_in *client,
1308                            const struct wol_msg *msg,
1309                            const struct in_addr *addr)
1310{
1311        int ret;
1312
1313        client->sin_addr.s_addr = addr->s_addr;
1314
1315        ret = sendto(sd, msg, sizeof(*msg), 0,
1316                     (sockaddr *)client, sizeof(*client));
1317        if (ret < 0) {
1318                syslog(LOG_ERR, "failed to send unicast wol\n");
1319                return false;
1320        }
1321
1322        return true;
1323}
1324
1325enum wol_delivery_type {
1326        OG_WOL_BROADCAST = 1,
1327        OG_WOL_UNICAST = 2
1328};
1329
[b9eb98b]1330//_____________________________________________________________________________________________________________
1331// Función: WakeUp
1332//
1333//       Descripción:
1334//              Enciende el ordenador cuya MAC se pasa como parámetro
1335//      Parámetros:
1336//              - s : Socket para enviar trama magic packet
[0cee7a6]1337//              - iph : Cadena con la dirección ip
[b9eb98b]1338//              - mac : Cadena con la dirección mac en formato XXXXXXXXXXXX
[0cee7a6]1339//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
[b9eb98b]1340//      Devuelve:
[9dea2d6]1341//              true: Si el proceso es correcto
1342//              false: En caso de ocurrir algún error
[b9eb98b]1343//_____________________________________________________________________________________________________________
[0cee7a6]1344//
[b38ed0d]1345bool WakeUp(int s, char* iph, char *mac, char *mar)
[0cee7a6]1346{
[429bd36]1347        unsigned int macaddr[OG_WOL_MACADDR_LEN];
[2baf362]1348        char HDaddress_bin[OG_WOL_MACADDR_LEN];
1349        struct sockaddr_in WakeUpCliente;
1350        struct wol_msg Trama_WakeUp;
1351        struct in_addr addr;
1352        bool ret;
1353        int i;
[b9eb98b]1354
1355        for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF)
1356                Trama_WakeUp.secuencia_FF[i] = 0xFF;
1357
[63a3d4d]1358        sscanf(mac, "%02x%02x%02x%02x%02x%02x",
[429bd36]1359               &macaddr[0], &macaddr[1], &macaddr[2],
1360               &macaddr[3], &macaddr[4], &macaddr[5]);
1361
1362        for (i = 0; i < 6; i++)
1363                HDaddress_bin[i] = (uint8_t)macaddr[i];
[b9eb98b]1364
1365        for (i = 0; i < 16; i++) // Segunda secuencia de la trama Wake Up , repetir 16 veces su la MAC
1366                memcpy(&Trama_WakeUp.macbin[i][0], &HDaddress_bin, 6);
1367
1368        /* Creación de socket del cliente que recibe la trama magic packet */
1369        WakeUpCliente.sin_family = AF_INET;
1370        WakeUpCliente.sin_port = htons((short) PUERTO_WAKEUP);
1371
[2baf362]1372        switch (atoi(mar)) {
1373        case OG_WOL_BROADCAST:
[b38ed0d]1374                ret = wake_up_broadcast(s, &WakeUpCliente, &Trama_WakeUp);
[2baf362]1375                break;
1376        case OG_WOL_UNICAST:
1377                if (inet_aton(iph, &addr) < 0) {
1378                        syslog(LOG_ERR, "bad IP address for unicast wol\n");
1379                        ret = false;
1380                        break;
1381                }
[b38ed0d]1382                ret = wake_up_unicast(s, &WakeUpCliente, &Trama_WakeUp, &addr);
[2baf362]1383                break;
1384        default:
1385                syslog(LOG_ERR, "unknown wol type\n");
1386                ret = false;
1387                break;
1388        }
1389        return ret;
[b9eb98b]1390}
1391// ________________________________________________________________________________________________________
1392// Función: RESPUESTA_Arrancar
1393//
1394//      Descripción:
[28cc16b]1395//              Respuesta del cliente al comando Arrancar
[b9eb98b]1396//      Parámetros:
1397//              - socket_c: Socket del cliente que envió el mensaje
1398//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1399//      Devuelve:
[9dea2d6]1400//              true: Si el proceso es correcto
1401//              false: En caso de ocurrir algún error
[b9eb98b]1402// ________________________________________________________________________________________________________
[212280e]1403static bool RESPUESTA_Arrancar(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1404{
[b9eb98b]1405        char msglog[LONSTD];
1406        Database db;
1407        Table tbl;
1408        int i;
1409        char *iph, *ido;
1410        char *tpc;
1411
[b56cbeb]1412        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1413                db.GetErrorErrStr(msglog);
[b56cbeb]1414                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1415                       __func__, __LINE__, msglog);
[9dea2d6]1416                return false;
[b9eb98b]1417        }
1418
1419        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1420        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1421
1422        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1423                liberaMemoria(iph);
1424                liberaMemoria(ido);
[b56cbeb]1425                syslog(LOG_ERR, "failed to register notification\n");
1426                return false;
[b9eb98b]1427        }
1428
1429        tpc = copiaParametro("tpc",ptrTrama); // Tipo de cliente (Plataforma y S.O.)
1430        if (clienteExistente(iph, &i)) // Actualiza estado
1431                strcpy(tbsockets[i].estado, tpc);
[eb99080]1432               
1433        liberaMemoria(iph);
1434        liberaMemoria(ido);
1435        liberaMemoria(tpc);
1436       
[b9eb98b]1437        db.Close(); // Cierra conexión
[9dea2d6]1438        return true;
[b9eb98b]1439}
1440// ________________________________________________________________________________________________________
1441// Función: RESPUESTA_Apagar
1442//
1443//      Descripción:
1444//              Respuesta del cliente al comando Apagar
1445//      Parámetros:
1446//              - socket_c: Socket del cliente que envió el mensaje
1447//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1448//      Devuelve:
[9dea2d6]1449//              true: Si el proceso es correcto
1450//              false: En caso de ocurrir algún error
[b9eb98b]1451// ________________________________________________________________________________________________________
[212280e]1452static bool RESPUESTA_Apagar(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1453{
[b9eb98b]1454        char msglog[LONSTD];
1455        Database db;
1456        Table tbl;
1457        int i;
1458        char *iph, *ido;
1459
[b56cbeb]1460        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1461                db.GetErrorErrStr(msglog);
[b56cbeb]1462                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1463                       __func__, __LINE__, msglog);
[9dea2d6]1464                return false;
[b9eb98b]1465        }
1466
1467        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1468        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1469
1470        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1471                liberaMemoria(iph);
1472                liberaMemoria(ido);
[b56cbeb]1473                syslog(LOG_ERR, "failed to register notification\n");
[9dea2d6]1474                return false; // Error al registrar notificacion
[b9eb98b]1475        }
1476
1477        if (clienteExistente(iph, &i)) // Actualiza estado
1478                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
[eb99080]1479       
1480        liberaMemoria(iph);
1481        liberaMemoria(ido);
1482       
[b9eb98b]1483        db.Close(); // Cierra conexión
[9dea2d6]1484        return true;
[b9eb98b]1485}
1486// ________________________________________________________________________________________________________
1487// Función: RESPUESTA_Reiniciar
1488//
1489//      Descripción:
1490//              Respuesta del cliente al comando Reiniciar
1491//      Parámetros:
1492//              - socket_c: Socket del cliente que envió el mensaje
1493//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1494//      Devuelve:
[9dea2d6]1495//              true: Si el proceso es correcto
1496//              false: En caso de ocurrir algún error
[b9eb98b]1497// ________________________________________________________________________________________________________
[212280e]1498static bool RESPUESTA_Reiniciar(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1499{
[b9eb98b]1500        char msglog[LONSTD];
1501        Database db;
1502        Table tbl;
1503        int i;
1504        char *iph, *ido;
1505
[b56cbeb]1506        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1507                db.GetErrorErrStr(msglog);
[b56cbeb]1508                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1509                       __func__, __LINE__, msglog);
[9dea2d6]1510                return false;
[b9eb98b]1511        }
1512
1513        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1514        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1515
1516        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1517                liberaMemoria(iph);
1518                liberaMemoria(ido);
[b56cbeb]1519                syslog(LOG_ERR, "failed to register notification\n");
[9dea2d6]1520                return false; // Error al registrar notificacion
[b9eb98b]1521        }
1522
1523        if (clienteExistente(iph, &i)) // Actualiza estado
1524                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
[eb99080]1525       
1526        liberaMemoria(iph);
1527        liberaMemoria(ido);
[b9eb98b]1528
1529        db.Close(); // Cierra conexión
[9dea2d6]1530        return true;
[b9eb98b]1531}
1532// ________________________________________________________________________________________________________
1533// Función: RESPUESTA_IniciarSesion
1534//
1535//      Descripción:
1536//              Respuesta del cliente al comando Iniciar Sesión
1537//      Parámetros:
1538//              - socket_c: Socket del cliente que envió el mensaje
1539//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1540//      Devuelve:
[9dea2d6]1541//              true: Si el proceso es correcto
1542//              false: En caso de ocurrir algún error
[b9eb98b]1543// ________________________________________________________________________________________________________
[212280e]1544static bool RESPUESTA_IniciarSesion(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1545{
[b9eb98b]1546        char msglog[LONSTD];
1547        Database db;
1548        Table tbl;
1549        int i;
1550        char *iph, *ido;
1551
[b56cbeb]1552        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1553                db.GetErrorErrStr(msglog);
[b56cbeb]1554                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1555                       __func__, __LINE__, msglog);
[9dea2d6]1556                return false;
[b9eb98b]1557        }
1558
1559        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1560        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1561
1562        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1563                liberaMemoria(iph);
1564                liberaMemoria(ido);
[b56cbeb]1565                syslog(LOG_ERR, "failed to register notification\n");
[9dea2d6]1566                return false; // Error al registrar notificacion
[b9eb98b]1567        }
1568
1569        if (clienteExistente(iph, &i)) // Actualiza estado
1570                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
[eb99080]1571               
1572        liberaMemoria(iph);
1573        liberaMemoria(ido);
1574               
[b9eb98b]1575        db.Close(); // Cierra conexión
[9dea2d6]1576        return true;
[b9eb98b]1577}
1578// ________________________________________________________________________________________________________
1579// Función: RESPUESTA_CrearImagen
1580//
1581//      Descripción:
1582//              Respuesta del cliente al comando CrearImagen
1583//      Parámetros:
1584//              - socket_c: Socket del cliente que envió el mensaje
1585//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1586//      Devuelve:
[9dea2d6]1587//              true: Si el proceso es correcto
1588//              false: En caso de ocurrir algún error
[b9eb98b]1589// ________________________________________________________________________________________________________
[212280e]1590static bool RESPUESTA_CrearImagen(TRAMA* ptrTrama, struct og_client *cli)
[eb99080]1591{
[b9eb98b]1592        char msglog[LONSTD];
1593        Database db;
1594        Table tbl;
[599c505]1595        char *iph, *dsk, *par, *cpt, *ipr, *ido;
[b9eb98b]1596        char *idi;
[f74067f]1597        bool res;
[b9eb98b]1598
[b56cbeb]1599        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1600                db.GetErrorErrStr(msglog);
[b56cbeb]1601                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1602                       __func__, __LINE__, msglog);
[9dea2d6]1603                return false;
[b9eb98b]1604        }
1605
1606        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1607        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1608
1609        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1610                liberaMemoria(iph);
1611                liberaMemoria(ido);
[b56cbeb]1612                syslog(LOG_ERR, "failed to register notification\n");
[9dea2d6]1613                return false; // Error al registrar notificacion
[b9eb98b]1614        }
1615
1616        // Acciones posteriores
1617        idi = copiaParametro("idi",ptrTrama);
[599c505]1618        dsk = copiaParametro("dsk",ptrTrama);
[b9eb98b]1619        par = copiaParametro("par",ptrTrama);
1620        cpt = copiaParametro("cpt",ptrTrama);
1621        ipr = copiaParametro("ipr",ptrTrama);
1622
[599c505]1623        res=actualizaCreacionImagen(db, tbl, idi, dsk, par, cpt, ipr, ido);
[eb99080]1624
1625        liberaMemoria(idi);
1626        liberaMemoria(par);
1627        liberaMemoria(cpt);
1628        liberaMemoria(ipr);
[b56cbeb]1629
[eb99080]1630        if(!res){
[b56cbeb]1631                syslog(LOG_ERR, "Problem processing update\n");
1632                db.Close();
[9dea2d6]1633                return false;
[b9eb98b]1634        }
1635
1636        db.Close(); // Cierra conexión
[9dea2d6]1637        return true;
[b9eb98b]1638}
1639// ________________________________________________________________________________________________________
1640// Función: actualizaCreacionImagen
1641//
1642//      Descripción:
1643//              Esta función actualiza la base de datos con el resultado de la creación de una imagen
1644//      Parámetros:
1645//              - db: Objeto base de datos (ya operativo)
1646//              - tbl: Objeto tabla
1647//              - idi: Identificador de la imagen
[599c505]1648//              - dsk: Disco de donde se creó
[b9eb98b]1649//              - par: Partición de donde se creó
1650//              - cpt: Código de partición
1651//              - ipr: Ip del repositorio
1652//              - ido: Identificador del ordenador modelo
1653//      Devuelve:
[9dea2d6]1654//              true: Si el proceso es correcto
1655//              false: En caso de ocurrir algún error
[b9eb98b]1656// ________________________________________________________________________________________________________
[59fb4d5]1657bool actualizaCreacionImagen(Database db, Table tbl, char *idi, char *dsk,
1658                             char *par, char *cpt, char *ipr, char *ido)
1659{
[b9eb98b]1660        char msglog[LONSTD], sqlstr[LONSQL];
[ed05cd5]1661        int idr,ifs;
[b9eb98b]1662
[80d1dfd]1663        /* Toma identificador del repositorio correspondiente al ordenador modelo */
[599c505]1664        snprintf(sqlstr, LONSQL,
1665                        "SELECT repositorios.idrepositorio"
[80d1dfd]1666                        "  FROM repositorios"
1667                        "  LEFT JOIN ordenadores USING (idrepositorio)"
1668                        " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
[b9eb98b]1669
[b56cbeb]1670        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]1671                db.GetErrorErrStr(msglog);
[b56cbeb]1672                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1673                       __func__, __LINE__, msglog);
[9dea2d6]1674                return false;
[b9eb98b]1675        }
1676        if (!tbl.Get("idrepositorio", idr)) { // Toma dato
1677                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]1678                og_info(msglog);
[9dea2d6]1679                return false;
[b9eb98b]1680        }
1681
1682        /* Toma identificador del perfilsoftware */
[599c505]1683        snprintf(sqlstr, LONSQL,
1684                        "SELECT idperfilsoft"
1685                        "  FROM ordenadores_particiones"
1686                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
[b9eb98b]1687
[b56cbeb]1688        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]1689                db.GetErrorErrStr(msglog);
[b56cbeb]1690                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1691                       __func__, __LINE__, msglog);
[9dea2d6]1692                return false;
[b9eb98b]1693        }
1694        if (!tbl.Get("idperfilsoft", ifs)) { // Toma dato
1695                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]1696                og_info(msglog);
[9dea2d6]1697                return false;
[b9eb98b]1698        }
1699
1700        /* Actualizar los datos de la imagen */
[599c505]1701        snprintf(sqlstr, LONSQL,
[faee12e]1702                "UPDATE imagenes"
1703                "   SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
1704                "       idperfilsoft=%d, idrepositorio=%d,"
1705                "       fechacreacion=NOW(), revision=revision+1"
1706                " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
[b9eb98b]1707
[b56cbeb]1708        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]1709                db.GetErrorErrStr(msglog);
[b56cbeb]1710                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1711                       __func__, __LINE__, msglog);
[9dea2d6]1712                return false;
[b9eb98b]1713        }
[faee12e]1714        /* Actualizar los datos en el cliente */
1715        snprintf(sqlstr, LONSQL,
1716                "UPDATE ordenadores_particiones"
[ed05cd5]1717                "   SET idimagen=%s, revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
1718                "       fechadespliegue=NOW()"
[faee12e]1719                " WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
[ed05cd5]1720                idi, idi, ido, dsk, par);
[b56cbeb]1721        if (!db.Execute(sqlstr, tbl)) {
[faee12e]1722                db.GetErrorErrStr(msglog);
[b56cbeb]1723                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1724                       __func__, __LINE__, msglog);
[9dea2d6]1725                return false;
[faee12e]1726        }
[9dea2d6]1727        return true;
[b9eb98b]1728}
1729// ________________________________________________________________________________________________________
[eb99080]1730// Función: CrearImagenBasica
1731//
1732//      Descripción:
1733//              Crea una imagen basica usando sincronización
1734//      Parámetros:
1735//              - socket_c: Socket de la consola al envió el mensaje
1736//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1737//      Devuelve:
[9dea2d6]1738//              true: Si el proceso es correcto
1739//              false: En caso de ocurrir algún error
[eb99080]1740// ________________________________________________________________________________________________________
[212280e]1741static bool CrearImagenBasica(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1742{
[eb99080]1743        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]1744                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]1745                return false;
[eb99080]1746        }
[212280e]1747        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]1748        return true;
[eb99080]1749}
1750// ________________________________________________________________________________________________________
1751// Función: RESPUESTA_CrearImagenBasica
1752//
1753//      Descripción:
1754//              Respuesta del cliente al comando CrearImagenBasica
1755//      Parámetros:
1756//              - socket_c: Socket del cliente que envió el mensaje
1757//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1758//      Devuelve:
[9dea2d6]1759//              true: Si el proceso es correcto
1760//              false: En caso de ocurrir algún error
[eb99080]1761// ________________________________________________________________________________________________________
[212280e]1762static bool RESPUESTA_CrearImagenBasica(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1763{
[212280e]1764        // La misma respuesta que la creación de imagen monolítica
1765        return RESPUESTA_CrearImagen(ptrTrama, cli);
[eb99080]1766}
1767// ________________________________________________________________________________________________________
1768// Función: CrearSoftIncremental
1769//
1770//      Descripción:
1771//              Crea una imagen incremental entre una partición de un disco y una imagen ya creada guardandola en el
1772//              mismo repositorio y en la misma carpeta donde está la imagen básica
1773//      Parámetros:
1774//              - socket_c: Socket de la consola al envió el mensaje
1775//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1776//      Devuelve:
[9dea2d6]1777//              true: Si el proceso es correcto
1778//              false: En caso de ocurrir algún error
[eb99080]1779// ________________________________________________________________________________________________________
[212280e]1780static bool CrearSoftIncremental(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1781{
[eb99080]1782        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]1783                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]1784                return false;
[eb99080]1785        }
[212280e]1786        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]1787        return true;
[eb99080]1788}
1789// ________________________________________________________________________________________________________
1790// Función: RESPUESTA_CrearSoftIncremental
1791//
1792//      Descripción:
1793//              Respuesta del cliente al comando crearImagenDiferencial
1794//      Parámetros:
1795//              - socket_c: Socket del cliente que envió el mensaje
1796//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1797//      Devuelve:
[9dea2d6]1798//              true: Si el proceso es correcto
1799//              false: En caso de ocurrir algún error
[eb99080]1800// ________________________________________________________________________________________________________
[212280e]1801static bool RESPUESTA_CrearSoftIncremental(TRAMA* ptrTrama, struct og_client *cli)
[eb99080]1802{
1803        Database db;
1804        Table tbl;
1805        char *iph,*par,*ido,*idf;
1806        int ifs;
1807        char msglog[LONSTD],sqlstr[LONSQL];
1808
[b56cbeb]1809        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[eb99080]1810                db.GetErrorErrStr(msglog);
[b56cbeb]1811                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1812                       __func__, __LINE__, msglog);
[9dea2d6]1813                return false;
[eb99080]1814        }
1815
1816        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1817        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1818
1819        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1820                liberaMemoria(iph);
[b56cbeb]1821                liberaMemoria(ido);
1822                syslog(LOG_ERR, "failed to register notification\n");
1823                return false;
[eb99080]1824        }
1825
1826        par = copiaParametro("par",ptrTrama);
1827
1828        /* Toma identificador del perfilsoftware creado por el inventario de software */
1829        sprintf(sqlstr,"SELECT idperfilsoft FROM ordenadores_particiones WHERE idordenador=%s AND numpar=%s",ido,par);
1830       
1831        liberaMemoria(iph);
1832        liberaMemoria(ido);     
1833        liberaMemoria(par);     
[b56cbeb]1834
1835        if (!db.Execute(sqlstr, tbl)) {
[eb99080]1836                db.GetErrorErrStr(msglog);
[b56cbeb]1837                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1838                       __func__, __LINE__, msglog);
[9dea2d6]1839                return false;
[eb99080]1840        }
1841        if (!tbl.Get("idperfilsoft", ifs)) { // Toma dato
1842                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]1843                og_info(msglog);
[9dea2d6]1844                return false;
[eb99080]1845        }
1846
1847        /* Actualizar los datos de la imagen */
1848        idf = copiaParametro("idf",ptrTrama);
1849        sprintf(sqlstr,"UPDATE imagenes SET idperfilsoft=%d WHERE idimagen=%s",ifs,idf);
1850        liberaMemoria(idf);     
[b56cbeb]1851
1852        if (!db.Execute(sqlstr, tbl)) {
[eb99080]1853                db.GetErrorErrStr(msglog);
[b56cbeb]1854                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
1855                       __func__, __LINE__, msglog);
[9dea2d6]1856                return false;
[eb99080]1857        }
1858        db.Close(); // Cierra conexión
[9dea2d6]1859        return true;
[eb99080]1860}
1861// ________________________________________________________________________________________________________
1862// Función: RestaurarImagenBasica
1863//
1864//      Descripción:
1865//              Restaura una imagen básica en una partición
1866//      Parámetros:
1867//              - socket_c: Socket de la consola al envió el mensaje
1868//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1869//      Devuelve:
[9dea2d6]1870//              true: Si el proceso es correcto
1871//              false: En caso de ocurrir algún error
[eb99080]1872// ________________________________________________________________________________________________________
[212280e]1873static bool RestaurarImagenBasica(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1874{
[eb99080]1875        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]1876                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]1877                return false;
[eb99080]1878        }
[212280e]1879        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]1880        return true;
[eb99080]1881}
1882// ________________________________________________________________________________________________________
1883// Función: RestaurarSoftIncremental
1884//
1885//      Descripción:
1886//              Restaura una imagen básica junto con software incremental en una partición
1887//      Parámetros:
1888//              - socket_c: Socket de la consola al envió el mensaje
1889//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1890//      Devuelve:
[9dea2d6]1891//              true: Si el proceso es correcto
1892//              false: En caso de ocurrir algún error
[eb99080]1893// ________________________________________________________________________________________________________
[212280e]1894static bool RestaurarSoftIncremental(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1895{
[eb99080]1896        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]1897                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]1898                return false;
[eb99080]1899        }
[212280e]1900        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]1901        return true;
[eb99080]1902}
1903// ________________________________________________________________________________________________________
[b9eb98b]1904// Función: RESPUESTA_RestaurarImagen
1905//
1906//      Descripción:
1907//              Respuesta del cliente al comando RestaurarImagen
1908//      Parámetros:
1909//              - socket_c: Socket del cliente que envió el mensaje
1910//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1911//      Devuelve:
[9dea2d6]1912//              true: Si el proceso es correcto
1913//              false: En caso de ocurrir algún error
[b9eb98b]1914// ________________________________________________________________________________________________________
[eb99080]1915//
[212280e]1916static bool RESPUESTA_RestaurarImagen(TRAMA* ptrTrama, struct og_client *cli)
[eb99080]1917{
[b9eb98b]1918        char msglog[LONSTD];
1919        Database db;
1920        Table tbl;
[f74067f]1921        bool res;
[6ee505f]1922        char *iph, *ido, *idi, *dsk, *par, *ifs, *cfg;
[b9eb98b]1923
[b56cbeb]1924        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]1925                db.GetErrorErrStr(msglog);
[b56cbeb]1926                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
1927                       __func__, __LINE__, msglog);
[9dea2d6]1928                return false;
[b9eb98b]1929        }
1930
1931        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1932        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1933
1934        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]1935                liberaMemoria(iph);
[b56cbeb]1936                liberaMemoria(ido);
1937                syslog(LOG_ERR, "failed to register notification\n");
1938                return false;
[b9eb98b]1939        }
1940
1941        // Acciones posteriores
1942        idi = copiaParametro("idi",ptrTrama); // Toma identificador de la imagen
[599c505]1943        dsk = copiaParametro("dsk",ptrTrama); // Número de disco
[b9eb98b]1944        par = copiaParametro("par",ptrTrama); // Número de partición
1945        ifs = copiaParametro("ifs",ptrTrama); // Identificador del perfil software contenido
[6ee505f]1946        cfg = copiaParametro("cfg",ptrTrama); // Configuración de discos
1947        if(cfg){
1948                actualizaConfiguracion(db, tbl, cfg, atoi(ido)); // Actualiza la configuración del ordenador
1949                liberaMemoria(cfg);     
1950        }
[599c505]1951        res=actualizaRestauracionImagen(db, tbl, idi, dsk, par, ido, ifs);
[eb99080]1952       
1953        liberaMemoria(iph);
[6ee505f]1954        liberaMemoria(ido);
[eb99080]1955        liberaMemoria(idi);
1956        liberaMemoria(par);
1957        liberaMemoria(ifs);
1958
1959        if(!res){
[b56cbeb]1960                syslog(LOG_ERR, "Problem after restoring image\n");
1961                db.Close();
[9dea2d6]1962                return false;
[b9eb98b]1963        }
1964
1965        db.Close(); // Cierra conexión
[9dea2d6]1966        return true;
[b9eb98b]1967}
1968// ________________________________________________________________________________________________________
[eb99080]1969//
1970// Función: RESPUESTA_RestaurarImagenBasica
1971//
1972//      Descripción:
1973//              Respuesta del cliente al comando RestaurarImagen
1974//      Parámetros:
1975//              - socket_c: Socket del cliente que envió el mensaje
1976//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1977//      Devuelve:
[9dea2d6]1978//              true: Si el proceso es correcto
1979//              false: En caso de ocurrir algún error
[eb99080]1980// ________________________________________________________________________________________________________
1981//
[212280e]1982static bool RESPUESTA_RestaurarImagenBasica(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1983{
[212280e]1984        return RESPUESTA_RestaurarImagen(ptrTrama, cli);
[eb99080]1985}
1986// ________________________________________________________________________________________________________
1987// Función: RESPUESTA_RestaurarSoftIncremental
1988//
1989//      Descripción:
1990//              Respuesta del cliente al comando RestaurarSoftIncremental
1991//      Parámetros:
1992//              - socket_c: Socket del cliente que envió el mensaje
1993//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1994//      Devuelve:
[9dea2d6]1995//              true: Si el proceso es correcto
1996//              false: En caso de ocurrir algún error
[eb99080]1997// ________________________________________________________________________________________________________
[212280e]1998static bool RESPUESTA_RestaurarSoftIncremental(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]1999{
[212280e]2000        return RESPUESTA_RestaurarImagen(ptrTrama, cli);
[eb99080]2001}
2002// ________________________________________________________________________________________________________
[b9eb98b]2003// Función: actualizaRestauracionImagen
2004//
2005//      Descripción:
[eb99080]2006//              Esta función actualiza la base de datos con el resultado de la restauración de una imagen
[b9eb98b]2007//      Parámetros:
2008//              - db: Objeto base de datos (ya operativo)
2009//              - tbl: Objeto tabla
2010//              - idi: Identificador de la imagen
[599c505]2011//              - dsk: Disco de donde se restauró
[b9eb98b]2012//              - par: Partición de donde se restauró
2013//              - ido: Identificador del cliente donde se restauró
2014//              - ifs: Identificador del perfil software contenido      en la imagen
2015//      Devuelve:
[9dea2d6]2016//              true: Si el proceso es correcto
2017//              false: En caso de ocurrir algún error
[b9eb98b]2018// ________________________________________________________________________________________________________
[59fb4d5]2019bool actualizaRestauracionImagen(Database db, Table tbl, char *idi,
2020                                 char *dsk, char *par, char *ido, char *ifs)
2021{
[b9eb98b]2022        char msglog[LONSTD], sqlstr[LONSQL];
2023
2024        /* Actualizar los datos de la imagen */
[599c505]2025        snprintf(sqlstr, LONSQL,
2026                        "UPDATE ordenadores_particiones"
[60bbc25]2027                        "   SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
[9e3c02a]2028                        "       revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
2029                        "       idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
[c20cf9c]2030                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", idi, ifs, idi, ifs, ido, dsk, par);
[b9eb98b]2031
[b56cbeb]2032        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2033                db.GetErrorErrStr(msglog);
[b56cbeb]2034                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2035                       __func__, __LINE__, msglog);
[9dea2d6]2036                return false;
[b9eb98b]2037        }
[9dea2d6]2038        return true;
[b9eb98b]2039}
2040// ________________________________________________________________________________________________________
2041// Función: Configurar
2042//
2043//      Descripción:
2044//              Configura la tabla de particiones
2045//      Parámetros:
2046//              - socket_c: Socket de la consola al envió el mensaje
2047//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2048//      Devuelve:
[9dea2d6]2049//              true: Si el proceso es correcto
2050//              false: En caso de ocurrir algún error
[b9eb98b]2051// ________________________________________________________________________________________________________
[212280e]2052static bool Configurar(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]2053{
[b9eb98b]2054        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]2055                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]2056                return false;
[b9eb98b]2057        }
[212280e]2058        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]2059        return true;
[b9eb98b]2060}
2061// ________________________________________________________________________________________________________
2062// Función: RESPUESTA_Configurar
2063//
2064//      Descripción:
2065//              Respuesta del cliente al comando Configurar
2066//      Parámetros:
2067//              - socket_c: Socket del cliente que envió el mensaje
2068//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2069//      Devuelve:
[9dea2d6]2070//              true: Si el proceso es correcto
2071//              false: En caso de ocurrir algún error
[b9eb98b]2072// ________________________________________________________________________________________________________
[eb99080]2073//
[212280e]2074static bool RESPUESTA_Configurar(TRAMA* ptrTrama, struct og_client *ci)
[eb99080]2075{
[b9eb98b]2076        char msglog[LONSTD];
2077        Database db;
2078        Table tbl;
[f74067f]2079        bool res;
[b9eb98b]2080        char *iph, *ido,*cfg;
2081
[b56cbeb]2082        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]2083                db.GetErrorErrStr(msglog);
[b56cbeb]2084                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
2085                       __func__, __LINE__, msglog);
[9dea2d6]2086                return false;
[b9eb98b]2087        }
2088
2089        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2090        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2091
2092        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]2093                liberaMemoria(iph);
[b56cbeb]2094                liberaMemoria(ido);
2095                syslog(LOG_ERR, "failed to register notification\n");
2096                return false;
[b9eb98b]2097        }
2098
2099        cfg = copiaParametro("cfg",ptrTrama); // Toma configuración de particiones
[eb99080]2100        res=actualizaConfiguracion(db, tbl, cfg, atoi(ido)); // Actualiza la configuración del ordenador
2101       
2102        liberaMemoria(iph);
2103        liberaMemoria(ido);     
2104        liberaMemoria(cfg);     
[b56cbeb]2105
2106        if(!res){
2107                syslog(LOG_ERR, "Problem updating client configuration\n");
2108                return false;
[b9eb98b]2109        }
[b56cbeb]2110
[b9eb98b]2111        db.Close(); // Cierra conexión
[9dea2d6]2112        return true;
[b9eb98b]2113}
2114// ________________________________________________________________________________________________________
2115// Función: EjecutarScript
2116//
2117//      Descripción:
2118//              Ejecuta un script de código
2119//      Parámetros:
2120//              - socket_c: Socket de la consola al envió el mensaje
2121//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2122//      Devuelve:
[9dea2d6]2123//              true: Si el proceso es correcto
2124//              false: En caso de ocurrir algún error
[b9eb98b]2125// ________________________________________________________________________________________________________
[212280e]2126static bool EjecutarScript(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]2127{
[b9eb98b]2128        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
[212280e]2129                respuestaConsola(og_client_socket(cli), ptrTrama, false);
[9dea2d6]2130                return false;
[b9eb98b]2131        }
[212280e]2132        respuestaConsola(og_client_socket(cli), ptrTrama, true);
[9dea2d6]2133        return true;
[b9eb98b]2134}
2135// ________________________________________________________________________________________________________
2136// Función: RESPUESTA_EjecutarScript
2137//
2138//      Descripción:
2139//              Respuesta del cliente al comando EjecutarScript
2140//      Parámetros:
2141//              - socket_c: Socket del cliente que envió el mensaje
2142//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2143//      Devuelve:
[9dea2d6]2144//              true: Si el proceso es correcto
2145//              false: En caso de ocurrir algún error
[b9eb98b]2146// ________________________________________________________________________________________________________
[212280e]2147static bool RESPUESTA_EjecutarScript(TRAMA* ptrTrama, struct og_client *cli)
[827bac5]2148{
[b9eb98b]2149        char msglog[LONSTD];
2150        Database db;
2151        Table tbl;
[827bac5]2152        char *iph, *ido,*cfg;
[b9eb98b]2153
[b56cbeb]2154        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]2155                db.GetErrorErrStr(msglog);
[b56cbeb]2156                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
2157                       __func__, __LINE__, msglog);
[9dea2d6]2158                return false;
[b9eb98b]2159        }
2160
2161        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2162        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2163
2164        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]2165                liberaMemoria(iph);
[b56cbeb]2166                liberaMemoria(ido);
2167                syslog(LOG_ERR, "failed to register notification\n");
2168                return false;
[b9eb98b]2169        }
[eb99080]2170       
[827bac5]2171        cfg = copiaParametro("cfg",ptrTrama); // Toma configuración de particiones
[1c04180]2172        if(cfg){
[24df599]2173                actualizaConfiguracion(db, tbl, cfg, atoi(ido)); // Actualiza la configuración del ordenador
[1c04180]2174                liberaMemoria(cfg);     
2175        }
[827bac5]2176
[eb99080]2177        liberaMemoria(iph);
[827bac5]2178        liberaMemoria(ido);
[1c04180]2179
[eb99080]2180       
[b9eb98b]2181        db.Close(); // Cierra conexión
[9dea2d6]2182        return true;
[b9eb98b]2183}
2184// ________________________________________________________________________________________________________
2185// Función: RESPUESTA_InventarioHardware
2186//
2187//      Descripción:
2188//              Respuesta del cliente al comando InventarioHardware
2189//      Parámetros:
2190//              - socket_c: Socket del cliente que envió el mensaje
2191//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2192//      Devuelve:
[9dea2d6]2193//              true: Si el proceso es correcto
2194//              false: En caso de ocurrir algún error
[b9eb98b]2195// ________________________________________________________________________________________________________
[212280e]2196static bool RESPUESTA_InventarioHardware(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]2197{
[b9eb98b]2198        char msglog[LONSTD];
2199        Database db;
2200        Table tbl;
[f74067f]2201        bool res;
[b9eb98b]2202        char *iph, *ido, *idc, *npc, *hrd, *buffer;
2203
[b56cbeb]2204        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]2205                db.GetErrorErrStr(msglog);
[b56cbeb]2206                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
2207                       __func__, __LINE__, msglog);
[9dea2d6]2208                return false;
[b9eb98b]2209        }
[eb99080]2210
[b9eb98b]2211        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip del cliente
2212        ido = copiaParametro("ido",ptrTrama); // Toma identificador del cliente
2213
2214        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]2215                liberaMemoria(iph);
[b56cbeb]2216                liberaMemoria(ido);
2217                syslog(LOG_ERR, "failed to register notification\n");
2218                return false;
[b9eb98b]2219        }
2220        // Lee archivo de inventario enviado anteriormente
2221        hrd = copiaParametro("hrd",ptrTrama);
2222        buffer = rTrim(leeArchivo(hrd));
[eb99080]2223       
2224        npc = copiaParametro("npc",ptrTrama); 
2225        idc = copiaParametro("idc",ptrTrama); // Toma identificador del Centro
2226       
2227        if (buffer) 
2228                res=actualizaHardware(db, tbl, buffer, ido, npc, idc);
2229       
2230        liberaMemoria(iph);
2231        liberaMemoria(ido);                     
2232        liberaMemoria(npc);                     
2233        liberaMemoria(idc);             
2234        liberaMemoria(buffer);         
2235       
2236        if(!res){
[b56cbeb]2237                syslog(LOG_ERR, "Problem updating client configuration\n");
[9dea2d6]2238                return false;
[b9eb98b]2239        }
[eb99080]2240               
[b9eb98b]2241        db.Close(); // Cierra conexión
[9dea2d6]2242        return true;
[b9eb98b]2243}
2244// ________________________________________________________________________________________________________
2245// Función: actualizaHardware
2246//
2247//              Descripción:
2248//                      Actualiza la base de datos con la configuracion hardware del cliente
2249//              Parámetros:
2250//                      - db: Objeto base de datos (ya operativo)
2251//                      - tbl: Objeto tabla
2252//                      - hrd: cadena con el inventario hardware
2253//                      - ido: Identificador del ordenador
2254//                      - npc: Nombre del ordenador
2255//                      - idc: Identificador del centro o Unidad organizativa
2256// ________________________________________________________________________________________________________
[eb99080]2257//
[59fb4d5]2258bool actualizaHardware(Database db, Table tbl, char *hrd, char *ido, char *npc,
2259                       char *idc)
[eb99080]2260{
[b9eb98b]2261        char msglog[LONSTD], sqlstr[LONSQL];
2262        int idtipohardware, idperfilhard;
2263        int lon, i, j, aux;
[7f46c45]2264        bool retval;
[eb99080]2265        char *whard;
[b9eb98b]2266        int tbidhardware[MAXHARDWARE];
[eb99080]2267        char *tbHardware[MAXHARDWARE],*dualHardware[2], descripcion[250], strInt[LONINT], *idhardwares;
[b9eb98b]2268
2269        /* Toma Centro (Unidad Organizativa) */
2270        sprintf(sqlstr, "SELECT * FROM ordenadores WHERE idordenador=%s", ido);
2271
[b56cbeb]2272        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2273                db.GetErrorErrStr(msglog);
[b56cbeb]2274                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2275                       __func__, __LINE__, msglog);
[9dea2d6]2276                return false;
[b9eb98b]2277        }
2278        if (!tbl.Get("idperfilhard", idperfilhard)) { // Toma dato
2279                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2280                og_info(msglog);
[9dea2d6]2281                return false;
[b9eb98b]2282        }
[eb99080]2283        whard=escaparCadena(hrd); // Codificar comillas simples
2284        if(!whard)
[9dea2d6]2285                return false;
[b9eb98b]2286        /* Recorre componentes hardware*/
[eb99080]2287        lon = splitCadena(tbHardware, whard, '\n');
[b9eb98b]2288        if (lon > MAXHARDWARE)
2289                lon = MAXHARDWARE; // Limita el número de componentes hardware
2290        /*
2291         for (i=0;i<lon;i++){
2292         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
[9dea2d6]2293         RegistraLog(msglog,false);
[b9eb98b]2294         }
2295         */
2296        for (i = 0; i < lon; i++) {
2297                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
2298                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
[9dea2d6]2299                //RegistraLog(msglog,false);
[b9eb98b]2300                //sprintf(msglog,"valor: %s",dualHardware[1]);
[9dea2d6]2301                //RegistraLog(msglog,false);
[b9eb98b]2302                sprintf(sqlstr, "SELECT idtipohardware,descripcion FROM tipohardwares "
2303                        " WHERE nemonico='%s'", dualHardware[0]);
[b56cbeb]2304                if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2305                        db.GetErrorErrStr(msglog);
[b56cbeb]2306                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2307                               __func__, __LINE__, msglog);
[9dea2d6]2308                        return false;
[b9eb98b]2309                }
2310                if (tbl.ISEOF()) { //  Tipo de Hardware NO existente
2311                        sprintf(msglog, "%s: %s)", tbErrores[54], dualHardware[0]);
[9764185]2312                        og_info(msglog);
[9dea2d6]2313                        return false;
[b9eb98b]2314                } else { //  Tipo de Hardware Existe
2315                        if (!tbl.Get("idtipohardware", idtipohardware)) { // Toma dato
2316                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2317                                og_info(msglog);
[9dea2d6]2318                                return false;
[b9eb98b]2319                        }
2320                        if (!tbl.Get("descripcion", descripcion)) { // Toma dato
2321                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2322                                og_info(msglog);
[9dea2d6]2323                                return false;
[b9eb98b]2324                        }
2325
2326                        sprintf(sqlstr, "SELECT idhardware FROM hardwares "
2327                                " WHERE idtipohardware=%d AND descripcion='%s'",
2328                                        idtipohardware, dualHardware[1]);
2329
[b56cbeb]2330                        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2331                                db.GetErrorErrStr(msglog);
[b56cbeb]2332                                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2333                                       __func__, __LINE__, msglog);
[9dea2d6]2334                                return false;
[b9eb98b]2335                        }
2336
2337                        if (tbl.ISEOF()) { //  Hardware NO existente
[bde1389]2338                                sprintf(sqlstr, "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
[b9eb98b]2339                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
2340                                                dualHardware[1], idc);
2341                                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2342                                        db.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2343                                        og_info(msglog);
[9dea2d6]2344                                        return false;
[b9eb98b]2345                                }
2346                                // Recupera el identificador del hardware
2347                                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
[b56cbeb]2348                                if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2349                                        db.GetErrorErrStr(msglog);
[b56cbeb]2350                                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2351                                               __func__, __LINE__, msglog);
[9dea2d6]2352                                        return false;
[b9eb98b]2353                                }
2354                                if (!tbl.ISEOF()) { // Si existe registro
2355                                        if (!tbl.Get("identificador", tbidhardware[i])) {
2356                                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2357                                                og_info(msglog);
[9dea2d6]2358                                                return false;
[b9eb98b]2359                                        }
2360                                }
2361                        } else {
2362                                if (!tbl.Get("idhardware", tbidhardware[i])) { // Toma dato
2363                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2364                                        og_info(msglog);
[9dea2d6]2365                                        return false;
[b9eb98b]2366                                }
2367                        }
2368                }
2369        }
2370        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
2371
2372        for (i = 0; i < lon - 1; i++) {
2373                for (j = i + 1; j < lon; j++) {
2374                        if (tbidhardware[i] > tbidhardware[j]) {
2375                                aux = tbidhardware[i];
2376                                tbidhardware[i] = tbidhardware[j];
2377                                tbidhardware[j] = aux;
2378                        }
2379                }
2380        }
2381        /* Crea cadena de identificadores de componentes hardware separados por coma */
2382        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
2383        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
2384        idhardwares = reservaMemoria(sizeof(aux) * lon + lon);
2385        if (idhardwares == NULL) {
[b56cbeb]2386                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]2387                return false;
[b9eb98b]2388        }
2389        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
2390        for (i = 1; i < lon; i++)
2391                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
2392
2393        if (!cuestionPerfilHardware(db, tbl, idc, ido, idperfilhard, idhardwares,
2394                        npc, tbidhardware, lon)) {
[b56cbeb]2395                syslog(LOG_ERR, "Problem updating client hardware\n");
[9dea2d6]2396                retval=false;
[b9eb98b]2397        }
[7f46c45]2398        else {
[9dea2d6]2399                retval=true;
[7f46c45]2400        }
[eb99080]2401        liberaMemoria(whard);
[7f46c45]2402        liberaMemoria(idhardwares);
2403        return (retval);
[b9eb98b]2404}
2405// ________________________________________________________________________________________________________
2406// Función: cuestionPerfilHardware
2407//
2408//              Descripción:
2409//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
2410//              Parámetros:
2411//                      - db: Objeto base de datos (ya operativo)
2412//                      - tbl: Objeto tabla
2413//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
2414//                      - ido: Identificador del ordenador
2415//                      - tbidhardware: Identificador del tipo de hardware
2416//                      - con: Número de componentes detectados para configurar un el perfil hardware
2417//                      - npc: Nombre del cliente
2418// ________________________________________________________________________________________________________
[59fb4d5]2419bool cuestionPerfilHardware(Database db, Table tbl, char *idc, char *ido,
2420                int idperfilhardware, char *idhardwares, char *npc, int *tbidhardware,
[b9eb98b]2421                int lon)
2422{
2423        char msglog[LONSTD], *sqlstr;
2424        int i;
2425        int nwidperfilhard;
2426
2427        sqlstr = reservaMemoria(strlen(idhardwares)+LONSQL); // Reserva para escribir sentencia SQL
2428        if (sqlstr == NULL) {
[b56cbeb]2429                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]2430                return false;
[b9eb98b]2431        }
2432        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
2433        sprintf(sqlstr, "SELECT idperfilhard FROM"
2434                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
2435                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
2436                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
2437                " FROM  perfileshard_hardwares"
2438                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
2439                " WHERE idhardwares LIKE '%s'", idhardwares);
[b56cbeb]2440
2441        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2442                db.GetErrorErrStr(msglog);
[b56cbeb]2443                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2444                       __func__, __LINE__, msglog);
[7f46c45]2445                liberaMemoria(sqlstr);
[9dea2d6]2446                return false;
[b9eb98b]2447        }
2448        if (tbl.ISEOF()) { // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
2449                sprintf(sqlstr, "INSERT perfileshard  (descripcion,idcentro,grupoid)"
[bde1389]2450                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
[b9eb98b]2451                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2452                        db.GetErrorErrStr(msglog);
[9764185]2453                        og_info(msglog);
[7f46c45]2454                        liberaMemoria(sqlstr);
[9dea2d6]2455                        return false;
[b9eb98b]2456                }
2457                // Recupera el identificador del nuevo perfil hardware
2458                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
2459                if (!db.Execute(sqlstr, tbl)) { // Error al leer
2460                        db.GetErrorErrStr(msglog);
[9764185]2461                        og_info(msglog);
[7f46c45]2462                        liberaMemoria(sqlstr);
[9dea2d6]2463                        return false;
[b9eb98b]2464                }
2465                if (!tbl.ISEOF()) { // Si existe registro
2466                        if (!tbl.Get("identificador", nwidperfilhard)) {
2467                                tbl.GetErrorErrStr(msglog);
[9764185]2468                                og_info(msglog);
[7f46c45]2469                                liberaMemoria(sqlstr);
[9dea2d6]2470                                return false;
[b9eb98b]2471                        }
2472                }
2473                // Crea la relación entre perfiles y componenetes hardware
2474                for (i = 0; i < lon; i++) {
[bde1389]2475                        sprintf(sqlstr, "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
[b9eb98b]2476                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
2477                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2478                                db.GetErrorErrStr(msglog);
[9764185]2479                                og_info(msglog);
[7f46c45]2480                                liberaMemoria(sqlstr);
[9dea2d6]2481                                return false;
[b9eb98b]2482                        }
2483                }
2484        } else { // Existe un perfil con todos esos componentes
2485                if (!tbl.Get("idperfilhard", nwidperfilhard)) {
2486                        tbl.GetErrorErrStr(msglog);
[9764185]2487                        og_info(msglog);
[7f46c45]2488                        liberaMemoria(sqlstr);
[9dea2d6]2489                        return false;
[b9eb98b]2490                }
2491        }
2492        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
2493                // Actualiza el identificador del perfil hardware del ordenador
2494                sprintf(sqlstr, "UPDATE ordenadores SET idperfilhard=%d"
2495                        " WHERE idordenador=%s", nwidperfilhard, ido);
2496                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2497                        db.GetErrorErrStr(msglog);
[9764185]2498                        og_info(msglog);
[7f46c45]2499                        liberaMemoria(sqlstr);
[9dea2d6]2500                        return false;
[b9eb98b]2501                }
2502        }
2503        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
2504        sprintf(sqlstr, "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
2505                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
2506                " (SELECT DISTINCT idperfilhard from ordenadores))");
2507        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2508                db.GetErrorErrStr(msglog);
[9764185]2509                og_info(msglog);
[7f46c45]2510                liberaMemoria(sqlstr);
[9dea2d6]2511                return false;
[b9eb98b]2512        }
2513
2514        /* Eliminar Perfiles hardware que quedan húerfanos */
2515        sprintf(sqlstr, "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
[7f46c45]2516                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
[b9eb98b]2517        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2518                db.GetErrorErrStr(msglog);
[9764185]2519                og_info(msglog);
[7f46c45]2520                liberaMemoria(sqlstr);
[9dea2d6]2521                return false;
[b9eb98b]2522        }
2523        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
[7f46c45]2524        sprintf(sqlstr, "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
2525                        " (SELECT idperfilhard FROM perfileshard)");
[b9eb98b]2526        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2527                db.GetErrorErrStr(msglog);
[9764185]2528                og_info(msglog);
[7f46c45]2529                liberaMemoria(sqlstr);
[9dea2d6]2530                return false;
[b9eb98b]2531        }
[7f46c45]2532        liberaMemoria(sqlstr);
[9dea2d6]2533        return true;
[b9eb98b]2534}
2535// ________________________________________________________________________________________________________
2536// Función: RESPUESTA_InventarioSoftware
2537//
2538//      Descripción:
2539//              Respuesta del cliente al comando InventarioSoftware
2540//      Parámetros:
2541//              - socket_c: Socket del cliente que envió el mensaje
2542//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2543//      Devuelve:
[9dea2d6]2544//              true: Si el proceso es correcto
2545//              false: En caso de ocurrir algún error
[b9eb98b]2546// ________________________________________________________________________________________________________
[212280e]2547static bool RESPUESTA_InventarioSoftware(TRAMA* ptrTrama, struct og_client *cli)
[59fb4d5]2548{
[b9eb98b]2549        char msglog[LONSTD];
2550        Database db;
2551        Table tbl;
[f74067f]2552        bool res;
[b9eb98b]2553        char *iph, *ido, *npc, *idc, *par, *sft, *buffer;
2554
[b56cbeb]2555        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]2556                db.GetErrorErrStr(msglog);
[b56cbeb]2557                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
2558                       __func__, __LINE__, msglog);
[9dea2d6]2559                return false;
[b9eb98b]2560        }
2561
2562        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2563        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2564
2565        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
[eb99080]2566                liberaMemoria(iph);
[b56cbeb]2567                liberaMemoria(ido);
2568                syslog(LOG_ERR, "failed to register notification\n");
2569                return false;
[b9eb98b]2570        }
[b56cbeb]2571
[eb99080]2572        npc = copiaParametro("npc",ptrTrama); 
2573        idc = copiaParametro("idc",ptrTrama); // Toma identificador del Centro 
[b9eb98b]2574        par = copiaParametro("par",ptrTrama);
2575        sft = copiaParametro("sft",ptrTrama);
2576
2577        buffer = rTrim(leeArchivo(sft));
[eb99080]2578        if (buffer)
2579                res=actualizaSoftware(db, tbl, buffer, par, ido, npc, idc);
2580
2581        liberaMemoria(iph);
2582        liberaMemoria(ido);     
2583        liberaMemoria(npc);     
2584        liberaMemoria(idc);     
2585        liberaMemoria(par);     
2586        liberaMemoria(sft);     
2587
2588        if(!res){
[b56cbeb]2589                syslog(LOG_ERR, "cannot update software\n");
[9dea2d6]2590                return false;
[b56cbeb]2591        }
2592
[b9eb98b]2593        db.Close(); // Cierra conexión
[9dea2d6]2594        return true;
[b9eb98b]2595}
2596// ________________________________________________________________________________________________________
2597// Función: actualizaSoftware
2598//
2599//      Descripción:
2600//              Actualiza la base de datos con la configuración software del cliente
2601//      Parámetros:
2602//              - db: Objeto base de datos (ya operativo)
2603//              - tbl: Objeto tabla
2604//              - sft: cadena con el inventario software
2605//              - par: Número de la partición
2606//              - ido: Identificador del ordenador del cliente en la tabla
2607//              - npc: Nombre del ordenador
2608//              - idc: Identificador del centro o Unidad organizativa
2609//      Devuelve:
[9dea2d6]2610//              true: Si el proceso es correcto
2611//              false: En caso de ocurrir algún error
[8712fd9]2612//
2613//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
[b9eb98b]2614// ________________________________________________________________________________________________________
[59fb4d5]2615bool actualizaSoftware(Database db, Table tbl, char *sft, char *par,char *ido,
2616                       char *npc, char *idc)
[eb99080]2617{
[8712fd9]2618        int i, j, lon, aux, idperfilsoft, idnombreso;
[7f46c45]2619        bool retval;
[eb99080]2620        char *wsft;
[b9eb98b]2621        int tbidsoftware[MAXSOFTWARE];
[eb99080]2622        char *tbSoftware[MAXSOFTWARE],msglog[LONSTD], sqlstr[LONSQL], strInt[LONINT], *idsoftwares;
[b9eb98b]2623
2624        /* Toma Centro (Unidad Organizativa) y perfil software */
2625        sprintf(sqlstr, "SELECT idperfilsoft,numpar"
2626                " FROM ordenadores_particiones"
2627                " WHERE idordenador=%s", ido);
2628
[b56cbeb]2629        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2630                db.GetErrorErrStr(msglog);
[b56cbeb]2631                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2632                       __func__, __LINE__, msglog);
[9dea2d6]2633                return false;
[b9eb98b]2634        }
2635        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
2636        while (!tbl.ISEOF()) { // Recorre particiones
2637                if (!tbl.Get("numpar", aux)) {
2638                        tbl.GetErrorErrStr(msglog);
[9764185]2639                        og_info(msglog);
[9dea2d6]2640                        return false;
[b9eb98b]2641                }
2642                if (aux == atoi(par)) { // Se encuentra la partición
2643                        if (!tbl.Get("idperfilsoft", idperfilsoft)) {
2644                                tbl.GetErrorErrStr(msglog);
[9764185]2645                                og_info(msglog);
[9dea2d6]2646                                return false;
[b9eb98b]2647                        }
2648                        break;
2649                }
2650                tbl.MoveNext();
2651        }
[eb99080]2652        wsft=escaparCadena(sft); // Codificar comillas simples
2653        if(!wsft)
[9dea2d6]2654                return false;
[b9eb98b]2655
2656        /* Recorre componentes software*/
[eb99080]2657        lon = splitCadena(tbSoftware, wsft, '\n');
2658
[b9eb98b]2659        if (lon == 0)
[9dea2d6]2660                return true; // No hay lineas que procesar
[b9eb98b]2661        if (lon > MAXSOFTWARE)
2662                lon = MAXSOFTWARE; // Limita el número de componentes software
2663
2664        for (i = 0; i < lon; i++) {
[8712fd9]2665                // Primera línea es el sistema operativo: se obtiene identificador
2666                if (i == 0) {
2667                        idnombreso = checkDato(db, tbl, rTrim(tbSoftware[i]), "nombresos", "nombreso", "idnombreso");
2668                        continue;
2669                }
2670
[b9eb98b]2671                sprintf(sqlstr,
2672                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
2673                                rTrim(tbSoftware[i]));
2674
[b56cbeb]2675                if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2676                        db.GetErrorErrStr(msglog);
[b56cbeb]2677                        syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2678                               __func__, __LINE__, msglog);
[9dea2d6]2679                        return false;
[b9eb98b]2680                }
2681
2682                if (tbl.ISEOF()) { //  Software NO existente
[bde1389]2683                        sprintf(sqlstr, "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
[b9eb98b]2684                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
2685
2686                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2687                                db.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2688                                og_info(msglog);
[9dea2d6]2689                                return false;
[b9eb98b]2690                        }
2691                        // Recupera el identificador del software
2692                        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
2693                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2694                                db.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2695                                og_info(msglog);
[9dea2d6]2696                                return false;
[b9eb98b]2697                        }
2698                        if (!tbl.ISEOF()) { // Si existe registro
2699                                if (!tbl.Get("identificador", tbidsoftware[i])) {
2700                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2701                                        og_info(msglog);
[9dea2d6]2702                                        return false;
[b9eb98b]2703                                }
2704                        }
2705                } else {
2706                        if (!tbl.Get("idsoftware", tbidsoftware[i])) { // Toma dato
2707                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
[9764185]2708                                og_info(msglog);
[9dea2d6]2709                                return false;
[b9eb98b]2710                        }
2711                }
2712        }
2713
2714        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
2715
2716        for (i = 0; i < lon - 1; i++) {
2717                for (j = i + 1; j < lon; j++) {
2718                        if (tbidsoftware[i] > tbidsoftware[j]) {
2719                                aux = tbidsoftware[i];
2720                                tbidsoftware[i] = tbidsoftware[j];
2721                                tbidsoftware[j] = aux;
2722                        }
2723                }
2724        }
2725        /* Crea cadena de identificadores de componentes software separados por coma */
2726        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
2727        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
2728        idsoftwares = reservaMemoria((sizeof(aux)+1) * lon + lon);
2729        if (idsoftwares == NULL) {
[b56cbeb]2730                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]2731                return false;
[b9eb98b]2732        }
2733        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
2734        for (i = 1; i < lon; i++)
2735                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
2736
2737        // Comprueba existencia de perfil software y actualización de éste para el ordenador
[8712fd9]2738        if (!cuestionPerfilSoftware(db, tbl, idc, ido, idperfilsoft, idnombreso, idsoftwares, 
[b9eb98b]2739                        npc, par, tbidsoftware, lon)) {
[b56cbeb]2740                syslog(LOG_ERR, "cannot update software\n");
[9764185]2741                og_info(msglog);
[9dea2d6]2742                retval=false;
[b9eb98b]2743        }
[7f46c45]2744        else {
[9dea2d6]2745                retval=true;
[7f46c45]2746        }
[eb99080]2747        liberaMemoria(wsft);
[7f46c45]2748        liberaMemoria(idsoftwares);
2749        return (retval);
[b9eb98b]2750}
2751// ________________________________________________________________________________________________________
2752// Función: CuestionPerfilSoftware
2753//
2754//      Parámetros:
2755//              - db: Objeto base de datos (ya operativo)
2756//              - tbl: Objeto tabla
2757//              - idcentro: Identificador del centro en la tabla
2758//              - ido: Identificador del ordenador del cliente en la tabla
[8712fd9]2759//              - idnombreso: Identificador del sistema operativo
[b9eb98b]2760//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
2761//              - npc: Nombre del ordenador del cliente
2762//              - particion: Número de la partición
2763//              - tbidsoftware: Array con los identificadores de componentes software
2764//              - lon: Número de componentes
2765//      Devuelve:
[9dea2d6]2766//              true: Si el proceso es correcto
2767//              false: En caso de ocurrir algún error
[8712fd9]2768//
2769//      Versión 1.1.0: Se incluye el sistema operativo. Autora: Irina Gómez - ETSII Universidad Sevilla
2770//_________________________________________________________________________________________________________
[59fb4d5]2771bool cuestionPerfilSoftware(Database db, Table tbl, char *idc, char *ido,
2772                            int idperfilsoftware, int idnombreso,
2773                            char *idsoftwares, char *npc, char *par,
2774                            int *tbidsoftware, int lon)
2775{
[b9eb98b]2776        char *sqlstr, msglog[LONSTD];
2777        int i, nwidperfilsoft;
2778
2779        sqlstr = reservaMemoria(strlen(idsoftwares)+LONSQL); // Reserva para escribir sentencia SQL
2780        if (sqlstr == NULL) {
[b56cbeb]2781                syslog(LOG_ERR, "%s:%d OOM\n", __FILE__, __LINE__);
[9dea2d6]2782                return false;
[b9eb98b]2783        }
2784        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
2785        sprintf(sqlstr, "SELECT idperfilsoft FROM"
2786                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
2787                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
2788                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
2789                " FROM  perfilessoft_softwares"
2790                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
2791                " WHERE idsoftwares LIKE '%s'", idsoftwares);
[b56cbeb]2792
2793        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2794                db.GetErrorErrStr(msglog);
[b56cbeb]2795                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2796                       __func__, __LINE__, msglog);
[7f46c45]2797                liberaMemoria(sqlstr);
[9dea2d6]2798                return false;
[b9eb98b]2799        }
2800        if (tbl.ISEOF()) { // No existe un perfil software con esos componentes de componentes software, lo crea
[8712fd9]2801                sprintf(sqlstr, "INSERT perfilessoft  (descripcion, idcentro, grupoid, idnombreso)"
2802                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0,%i)", npc, par, idc,idnombreso);
[b9eb98b]2803                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2804                        db.GetErrorErrStr(msglog);
[9764185]2805                        og_info(msglog);
[9dea2d6]2806                        return false;
[b9eb98b]2807                }
2808                // Recupera el identificador del nuevo perfil software
2809                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
2810                if (!db.Execute(sqlstr, tbl)) { // Error al leer
2811                        tbl.GetErrorErrStr(msglog);
[9764185]2812                        og_info(msglog);
[7f46c45]2813                        liberaMemoria(sqlstr);
[9dea2d6]2814                        return false;
[b9eb98b]2815                }
2816                if (!tbl.ISEOF()) { // Si existe registro
2817                        if (!tbl.Get("identificador", nwidperfilsoft)) {
2818                                tbl.GetErrorErrStr(msglog);
[9764185]2819                                og_info(msglog);
[7f46c45]2820                                liberaMemoria(sqlstr);
[9dea2d6]2821                                return false;
[b9eb98b]2822                        }
2823                }
2824                // Crea la relación entre perfiles y componenetes software
2825                for (i = 0; i < lon; i++) {
[7f46c45]2826                        sprintf(sqlstr, "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
[b9eb98b]2827                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
2828                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2829                                db.GetErrorErrStr(msglog);
[9764185]2830                                og_info(msglog);
[7f46c45]2831                                liberaMemoria(sqlstr);
[9dea2d6]2832                                return false;
[b9eb98b]2833                        }
2834                }
2835        } else { // Existe un perfil con todos esos componentes
2836                if (!tbl.Get("idperfilsoft", nwidperfilsoft)) {
2837                        tbl.GetErrorErrStr(msglog);
[9764185]2838                        og_info(msglog);
[7f46c45]2839                        liberaMemoria(sqlstr);
[9dea2d6]2840                        return false;
[b9eb98b]2841                }
2842        }
2843
2844        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
2845                // Actualiza el identificador del perfil software del ordenador
[7f46c45]2846                sprintf(sqlstr, "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
2847                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
[b9eb98b]2848                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2849                        db.GetErrorErrStr(msglog);
[9764185]2850                        og_info(msglog);
[7f46c45]2851                        liberaMemoria(sqlstr);
[9dea2d6]2852                        return false;
[b9eb98b]2853                }
2854        }
2855
2856        /* DEPURACIÓN DE PERFILES SOFTWARE */
2857
2858         /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
2859        sprintf(sqlstr, "DELETE FROM perfilessoft_softwares WHERE idperfilsoft IN "\
2860                " (SELECT idperfilsoft FROM perfilessoft WHERE idperfilsoft NOT IN"\
2861                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones) AND idperfilsoft NOT IN"\
2862                " (SELECT DISTINCT idperfilsoft from imagenes))");
2863        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2864                db.GetErrorErrStr(msglog);
[9764185]2865                og_info(msglog);
[7f46c45]2866                liberaMemoria(sqlstr);
[9dea2d6]2867                return false;
[b9eb98b]2868        }
2869        /* Eliminar Perfiles software que quedan húerfanos */
2870        sprintf(sqlstr, "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
2871                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
2872                " AND  idperfilsoft NOT IN"\
2873                " (SELECT DISTINCT idperfilsoft from imagenes)");
2874        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2875                db.GetErrorErrStr(msglog);
[9764185]2876                og_info(msglog);
[7f46c45]2877                liberaMemoria(sqlstr);
[9dea2d6]2878                return false;
[b9eb98b]2879        }
2880        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
[7f46c45]2881        sprintf(sqlstr, "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
2882                        " (SELECT idperfilsoft from perfilessoft)");
[b9eb98b]2883        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2884                db.GetErrorErrStr(msglog);
[9764185]2885                og_info(msglog);
[7f46c45]2886                liberaMemoria(sqlstr);
[9dea2d6]2887                return false;
[b9eb98b]2888        }
[7f46c45]2889        liberaMemoria(sqlstr);
[9dea2d6]2890        return true;
[b9eb98b]2891}
2892// ________________________________________________________________________________________________________
2893// Función: enviaArchivo
2894//
2895//      Descripción:
2896//              Envia un archivo por la red, por bloques
2897//      Parámetros:
2898//              - socket_c: Socket del cliente que envió el mensaje
2899//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2900//      Devuelve:
[9dea2d6]2901//              true: Si el proceso es correcto
2902//              false: En caso de ocurrir algún error
[b9eb98b]2903// ________________________________________________________________________________________________________
[212280e]2904static bool enviaArchivo(TRAMA *ptrTrama, struct og_client *cli)
[59fb4d5]2905{
[212280e]2906        int socket_c = og_client_socket(cli);
[b9eb98b]2907        char *nfl;
2908
2909        // Toma parámetros
2910        nfl = copiaParametro("nfl",ptrTrama); // Toma nombre completo del archivo
[07d2b73]2911        if (!sendArchivo(&socket_c, nfl)) {
[eb99080]2912                liberaMemoria(nfl);
[b56cbeb]2913                syslog(LOG_ERR, "Problem sending file\n");
[9dea2d6]2914                return false;
[b9eb98b]2915        }
[eb99080]2916        liberaMemoria(nfl);
[9dea2d6]2917        return true;
[b9eb98b]2918}
2919// ________________________________________________________________________________________________________
2920// Función: enviaArchivo
2921//
2922//      Descripción:
2923//              Envia un archivo por la red, por bloques
2924//      Parámetros:
2925//              - socket_c: Socket del cliente que envió el mensaje
2926//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2927//      Devuelve:
[9dea2d6]2928//              true: Si el proceso es correcto
2929//              false: En caso de ocurrir algún error
[b9eb98b]2930// ________________________________________________________________________________________________________
[212280e]2931static bool recibeArchivo(TRAMA *ptrTrama, struct og_client *cli)
[59fb4d5]2932{
[212280e]2933        int socket_c = og_client_socket(cli);
[b9eb98b]2934        char *nfl;
2935
2936        // Toma parámetros
2937        nfl = copiaParametro("nfl",ptrTrama); // Toma nombre completo del archivo
2938        ptrTrama->tipo = MSG_NOTIFICACION;
[07d2b73]2939        enviaFlag(&socket_c, ptrTrama);
2940        if (!recArchivo(&socket_c, nfl)) {
[eb99080]2941                liberaMemoria(nfl);
[b56cbeb]2942                syslog(LOG_ERR, "Problem receiving file\n");
[9dea2d6]2943                return false;
[b9eb98b]2944        }
[eb99080]2945        liberaMemoria(nfl);
[9dea2d6]2946        return true;
[b9eb98b]2947}
2948// ________________________________________________________________________________________________________
2949// Función: envioProgramacion
2950//
2951//      Descripción:
2952//              Envia un comando de actualización a todos los ordenadores que han sido programados con
2953//              alguna acción para que entren en el bucle de comandos pendientes y las ejecuten
2954//      Parámetros:
2955//              - socket_c: Socket del cliente que envió el mensaje
2956//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2957//      Devuelve:
[9dea2d6]2958//              true: Si el proceso es correcto
2959//              false: En caso de ocurrir algún error
[b9eb98b]2960// ________________________________________________________________________________________________________
[212280e]2961static bool envioProgramacion(TRAMA *ptrTrama, struct og_client *cli)
[b9eb98b]2962{
[507c75c]2963        char *ptrIP[MAXIMOS_CLIENTES],*ptrMacs[MAXIMOS_CLIENTES];
[b9eb98b]2964        char sqlstr[LONSQL], msglog[LONSTD];
[24df599]2965        char *idp,iph[LONIP],mac[LONMAC];
[b9eb98b]2966        Database db;
2967        Table tbl;
[507c75c]2968        int idx,idcomando,lon;
[b9eb98b]2969
[b56cbeb]2970        if (!db.Open(usuario, pasguor, datasource, catalog)) {
[b9eb98b]2971                db.GetErrorErrStr(msglog);
[b56cbeb]2972                syslog(LOG_ERR, "cannot open connection database (%s:%d) %s\n",
2973                       __func__, __LINE__, msglog);
[9dea2d6]2974                return false;
[b9eb98b]2975        }
2976
[eb99080]2977        idp = copiaParametro("idp",ptrTrama); // Toma identificador de la programación de la tabla acciones
[b9eb98b]2978
2979        sprintf(sqlstr, "SELECT ordenadores.ip,ordenadores.mac,acciones.idcomando FROM acciones "\
2980                        " INNER JOIN ordenadores ON ordenadores.ip=acciones.ip"\
2981                        " WHERE acciones.idprogramacion=%s",idp);
[eb99080]2982       
2983        liberaMemoria(idp);
[b56cbeb]2984
2985        if (!db.Execute(sqlstr, tbl)) {
[b9eb98b]2986                db.GetErrorErrStr(msglog);
[b56cbeb]2987                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
2988                       __func__, __LINE__, msglog);
[9dea2d6]2989                return false;
[b9eb98b]2990        }
[fcc271f]2991        db.Close();
[b9eb98b]2992        if(tbl.ISEOF())
[9dea2d6]2993                return true; // No existen registros
[b9eb98b]2994
2995        /* Prepara la trama de actualizacion */
2996
2997        initParametros(ptrTrama,0);
2998        ptrTrama->tipo=MSG_COMANDO;
2999        sprintf(ptrTrama->parametros, "nfn=Actualizar\r");
3000
3001        while (!tbl.ISEOF()) { // Recorre particiones
3002                if (!tbl.Get("ip", iph)) {
3003                        tbl.GetErrorErrStr(msglog);
[a1d02f4]3004                        syslog(LOG_ERR, "cannot find ip column in table: %s\n",
3005                               msglog);
[9dea2d6]3006                        return false;
[b9eb98b]3007                }
3008                if (!tbl.Get("idcomando", idcomando)) {
3009                        tbl.GetErrorErrStr(msglog);
[a1d02f4]3010                        syslog(LOG_ERR, "cannot find idcomando column in table: %s\n",
3011                               msglog);
[9dea2d6]3012                        return false;
[b9eb98b]3013                }
3014                if(idcomando==1){ // Arrancar
3015                        if (!tbl.Get("mac", mac)) {
3016                                tbl.GetErrorErrStr(msglog);
[a1d02f4]3017                                syslog(LOG_ERR, "cannot find mac column in table: %s\n",
3018                                       msglog);
[9dea2d6]3019                                return false;
[b9eb98b]3020                        }
[599c505]3021
[507c75c]3022                        lon = splitCadena(ptrIP, iph, ';');
3023                        lon = splitCadena(ptrMacs, mac, ';');
3024
[ad4ae52]3025                        // Se manda por broadcast y por unicast
[507c75c]3026                        if (!Levanta(ptrIP, ptrMacs, lon, (char*)"1"))
[9dea2d6]3027                                return false;
[ad4ae52]3028
[507c75c]3029                        if (!Levanta(ptrIP, ptrMacs, lon, (char*)"2"))
[9dea2d6]3030                                return false;
[ad4ae52]3031
[b9eb98b]3032                }
3033                if (clienteDisponible(iph, &idx)) { // Si el cliente puede recibir comandos
[f09aca6]3034                        int sock = tbsockets[idx].cli ? tbsockets[idx].cli->io.fd : -1;
3035
[b9eb98b]3036                        strcpy(tbsockets[idx].estado, CLIENTE_OCUPADO); // Actualiza el estado del cliente
[3e8fcf0]3037                        if (sock >= 0 && !mandaTrama(&sock, ptrTrama)) {
[b56cbeb]3038                                syslog(LOG_ERR, "failed to send response: %s\n",
3039                                       strerror(errno));
[b9eb98b]3040                        }
[b937298]3041                        //close(tbsockets[idx].sock); // Cierra el socket del cliente hasta nueva disponibilidad
[b9eb98b]3042                }
3043                tbl.MoveNext();
3044        }
[9dea2d6]3045        return true; // No existen registros
[b9eb98b]3046}
[8e0216a]3047
3048// This object stores function handler for messages
3049static struct {
3050        const char *nf; // Nombre de la función
[212280e]3051        bool (*fcn)(TRAMA *, struct og_client *cli);
[4665749]3052} tbfuncionesServer[] = {
[8e0216a]3053        { "InclusionCliente",                   InclusionCliente,       },
3054        { "InclusionClienteWinLnx",             InclusionClienteWinLnx, },
3055        { "AutoexecCliente",                    AutoexecCliente,        },
3056        { "ComandosPendientes",                 ComandosPendientes,     },
3057        { "DisponibilidadComandos",             DisponibilidadComandos, },
3058        { "RESPUESTA_Arrancar",                 RESPUESTA_Arrancar,     },
3059        { "RESPUESTA_Apagar",                   RESPUESTA_Apagar,       },
3060        { "RESPUESTA_Reiniciar",                RESPUESTA_Reiniciar,    },
3061        { "RESPUESTA_IniciarSesion",            RESPUESTA_IniciarSesion, },
3062        { "RESPUESTA_CrearImagen",              RESPUESTA_CrearImagen,  },
3063        { "CrearImagenBasica",                  CrearImagenBasica,      },
3064        { "RESPUESTA_CrearImagenBasica",        RESPUESTA_CrearImagenBasica, },
3065        { "CrearSoftIncremental",               CrearSoftIncremental,   },
3066        { "RESPUESTA_CrearSoftIncremental",     RESPUESTA_CrearSoftIncremental, },
3067        { "RESPUESTA_RestaurarImagen",          RESPUESTA_RestaurarImagen },
3068        { "RestaurarImagenBasica",              RestaurarImagenBasica, },
3069        { "RESPUESTA_RestaurarImagenBasica",    RESPUESTA_RestaurarImagenBasica, },
3070        { "RestaurarSoftIncremental",           RestaurarSoftIncremental, },
3071        { "RESPUESTA_RestaurarSoftIncremental", RESPUESTA_RestaurarSoftIncremental, },
3072        { "Configurar",                         Configurar,             },
3073        { "RESPUESTA_Configurar",               RESPUESTA_Configurar,   },
3074        { "EjecutarScript",                     EjecutarScript,         },
3075        { "RESPUESTA_EjecutarScript",           RESPUESTA_EjecutarScript, },
3076        { "RESPUESTA_InventarioHardware",       RESPUESTA_InventarioHardware, },
3077        { "RESPUESTA_InventarioSoftware",       RESPUESTA_InventarioSoftware, },
3078        { "enviaArchivo",                       enviaArchivo,           },
3079        { "recibeArchivo",                      recibeArchivo,          },
3080        { "envioProgramacion",                  envioProgramacion,      },
[4665749]3081        { NULL,                                 NULL,                   },
[8e0216a]3082};
3083
3084// ________________________________________________________________________________________________________
3085// Función: gestionaTrama
3086//
3087//              Descripción:
3088//                      Procesa las tramas recibidas .
3089//              Parametros:
3090//                      - s : Socket usado para comunicaciones
3091//      Devuelve:
[9dea2d6]3092//              true: Si el proceso es correcto
3093//              false: En caso de ocurrir algún error
[8e0216a]3094// ________________________________________________________________________________________________________
[b56cbeb]3095static void gestionaTrama(TRAMA *ptrTrama, struct og_client *cli)
[8e0216a]3096{
3097        int i, res;
3098        char *nfn;
3099
3100        if (ptrTrama){
3101                INTROaFINCAD(ptrTrama);
3102                nfn = copiaParametro("nfn",ptrTrama); // Toma nombre de la función
3103
[212280e]3104                for (i = 0; tbfuncionesServer[i].fcn; i++) {
3105                        if (!strncmp(tbfuncionesServer[i].nf, nfn,
3106                                     strlen(tbfuncionesServer[i].nf))) {
3107                                res = tbfuncionesServer[i].fcn(ptrTrama, cli);
[b56cbeb]3108                                if (!res) {
3109                                        syslog(LOG_ERR, "Failed handling of %s for client %s:%hu\n",
3110                                               tbfuncionesServer[i].nf,
3111                                               inet_ntoa(cli->addr.sin_addr),
3112                                               ntohs(cli->addr.sin_port));
3113                                } else {
3114                                        syslog(LOG_DEBUG, "Successful handling of %s for client %s:%hu\n",
3115                                               tbfuncionesServer[i].nf,
3116                                               inet_ntoa(cli->addr.sin_addr),
3117                                               ntohs(cli->addr.sin_port));
3118                                }
[212280e]3119                                break;
[8e0216a]3120                        }
3121                }
[ef6e3d2]3122                if (!tbfuncionesServer[i].fcn)
[f09aca6]3123                        syslog(LOG_ERR, "unknown request %s from client %s:%hu\n",
3124                               nfn, inet_ntoa(cli->addr.sin_addr),
3125                               ntohs(cli->addr.sin_port));
[ef6e3d2]3126
[8e0216a]3127                liberaMemoria(nfn);
[212280e]3128        }
3129}
3130
[f09aca6]3131static void og_client_release(struct ev_loop *loop, struct og_client *cli)
3132{
3133        if (cli->keepalive_idx >= 0) {
[2ed3a0c]3134                syslog(LOG_DEBUG, "closing keepalive connection for %s:%hu in slot %d\n",
[f09aca6]3135                       inet_ntoa(cli->addr.sin_addr),
3136                       ntohs(cli->addr.sin_port), cli->keepalive_idx);
3137                tbsockets[cli->keepalive_idx].cli = NULL;
3138        }
3139
3140        ev_io_stop(loop, &cli->io);
3141        close(cli->io.fd);
3142        free(cli);
3143}
3144
3145static void og_client_keepalive(struct ev_loop *loop, struct og_client *cli)
3146{
3147        struct og_client *old_cli;
3148
3149        old_cli = tbsockets[cli->keepalive_idx].cli;
3150        if (old_cli && old_cli != cli) {
[2ed3a0c]3151                syslog(LOG_DEBUG, "closing old keepalive connection for %s:%hu\n",
[f09aca6]3152                       inet_ntoa(old_cli->addr.sin_addr),
3153                       ntohs(old_cli->addr.sin_port));
3154
3155                og_client_release(loop, old_cli);
3156        }
3157        tbsockets[cli->keepalive_idx].cli = cli;
3158}
3159
3160static void og_client_reset_state(struct og_client *cli)
3161{
3162        cli->state = OG_CLIENT_RECEIVING_HEADER;
3163        cli->buf_len = 0;
3164}
3165
[d491dfd]3166static int og_client_state_recv_hdr(struct og_client *cli)
[212280e]3167{
3168        char hdrlen[LONHEXPRM];
[d491dfd]3169
3170        /* Still too short to validate protocol fingerprint and message
3171         * length.
3172         */
3173        if (cli->buf_len < 15 + LONHEXPRM)
3174                return 0;
3175
3176        if (strncmp(cli->buf, "@JMMLCAMDJ_MCDJ", 15)) {
3177                syslog(LOG_ERR, "bad fingerprint from client %s:%hu, closing\n",
3178                       inet_ntoa(cli->addr.sin_addr),
3179                       ntohs(cli->addr.sin_port));
3180                return -1;
3181        }
3182
3183        memcpy(hdrlen, &cli->buf[LONGITUD_CABECERATRAMA], LONHEXPRM);
3184        cli->msg_len = strtol(hdrlen, NULL, 16);
3185
3186        /* Header announces more that we can fit into buffer. */
3187        if (cli->msg_len >= sizeof(cli->buf)) {
3188                syslog(LOG_ERR, "too large message %u bytes from %s:%hu\n",
3189                       cli->msg_len, inet_ntoa(cli->addr.sin_addr),
3190                       ntohs(cli->addr.sin_port));
3191                return -1;
3192        }
3193
3194        return 1;
3195}
3196
[2226378]3197static TRAMA *og_msg_alloc(char *data, unsigned int len)
[d491dfd]3198{
[212280e]3199        TRAMA *ptrTrama;
[107b17a]3200
3201        ptrTrama = (TRAMA *)reservaMemoria(sizeof(TRAMA));
3202        if (!ptrTrama) {
3203                syslog(LOG_ERR, "OOM\n");
[2226378]3204                return NULL;
[107b17a]3205        }
3206
3207        initParametros(ptrTrama, len);
[2226378]3208        memcpy(ptrTrama, "@JMMLCAMDJ_MCDJ", LONGITUD_CABECERATRAMA);
[107b17a]3209        memcpy(ptrTrama->parametros, data, len);
3210        ptrTrama->lonprm = len;
3211
[2226378]3212        return ptrTrama;
3213}
[107b17a]3214
[2226378]3215static void og_msg_free(TRAMA *ptrTrama)
3216{
[107b17a]3217        liberaMemoria(ptrTrama->parametros);
3218        liberaMemoria(ptrTrama);
[2226378]3219}
3220
3221static int og_client_state_process_payload(struct og_client *cli)
3222{
3223        TRAMA *ptrTrama;
3224        char *data;
3225        int len;
3226
3227        len = cli->msg_len - (LONGITUD_CABECERATRAMA + LONHEXPRM);
3228        data = &cli->buf[LONGITUD_CABECERATRAMA + LONHEXPRM];
3229
3230        ptrTrama = og_msg_alloc(data, len);
3231        if (!ptrTrama)
3232                return -1;
3233
3234        gestionaTrama(ptrTrama, cli);
3235
3236        og_msg_free(ptrTrama);
[107b17a]3237
3238        return 1;
3239}
3240
[881f532]3241#define OG_CLIENTS_MAX  4096
[dbcc83d]3242#define OG_PARTITION_MAX 4
3243
3244struct og_partition {
3245        const char      *number;
3246        const char      *code;
3247        const char      *size;
3248        const char      *filesystem;
3249        const char      *format;
3250};
[881f532]3251
[01e77f4]3252struct og_sync_params {
3253        const char      *sync;
3254        const char      *diff;
3255        const char      *remove;
3256        const char      *compress;
3257        const char      *cleanup;
3258        const char      *cache;
3259        const char      *cleanup_cache;
3260        const char      *remove_dst;
[43c7da8]3261        const char      *diff_id;
3262        const char      *diff_name;
[f61fd9a]3263        const char      *path;
3264        const char      *method;
[01e77f4]3265};
3266
[95e6520]3267struct og_msg_params {
[881f532]3268        const char      *ips_array[OG_CLIENTS_MAX];
3269        const char      *mac_array[OG_CLIENTS_MAX];
[95e6520]3270        unsigned int    ips_array_len;
[5797e0b]3271        const char      *wol_type;
[7e4e5b5]3272        char            run_cmd[4096];
[7ab5f0c]3273        const char      *disk;
3274        const char      *partition;
[1a8ada1]3275        const char      *repository;
3276        const char      *name;
3277        const char      *id;
3278        const char      *code;
[1dde02e]3279        const char      *type;
3280        const char      *profile;
[dbcc83d]3281        const char      *cache;
3282        const char      *cache_size;
[ffd2965]3283        bool            echo;
[dbcc83d]3284        struct og_partition     partition_setup[OG_PARTITION_MAX];
[01e77f4]3285        struct og_sync_params sync_setup;
[54ecdbb]3286        uint64_t        flags;
[95e6520]3287};
3288
[54ecdbb]3289#define OG_REST_PARAM_ADDR                      (1UL << 0)
[ec5fe70]3290#define OG_REST_PARAM_MAC                       (1UL << 1)
3291#define OG_REST_PARAM_WOL_TYPE                  (1UL << 2)
[b403c7a]3292#define OG_REST_PARAM_RUN_CMD                   (1UL << 3)
[8901505]3293#define OG_REST_PARAM_DISK                      (1UL << 4)
3294#define OG_REST_PARAM_PARTITION                 (1UL << 5)
[abe2a88]3295#define OG_REST_PARAM_REPO                      (1UL << 6)
3296#define OG_REST_PARAM_NAME                      (1UL << 7)
3297#define OG_REST_PARAM_ID                        (1UL << 8)
3298#define OG_REST_PARAM_CODE                      (1UL << 9)
[ec4189b]3299#define OG_REST_PARAM_TYPE                      (1UL << 10)
3300#define OG_REST_PARAM_PROFILE                   (1UL << 11)
[3bc3b45]3301#define OG_REST_PARAM_CACHE                     (1UL << 12)
3302#define OG_REST_PARAM_CACHE_SIZE                (1UL << 13)
3303#define OG_REST_PARAM_PART_0                    (1UL << 14)
3304#define OG_REST_PARAM_PART_1                    (1UL << 15)
3305#define OG_REST_PARAM_PART_2                    (1UL << 16)
3306#define OG_REST_PARAM_PART_3                    (1UL << 17)
[82a1d5a]3307#define OG_REST_PARAM_SYNC_SYNC                 (1UL << 18)
3308#define OG_REST_PARAM_SYNC_DIFF                 (1UL << 19)
3309#define OG_REST_PARAM_SYNC_REMOVE               (1UL << 20)
3310#define OG_REST_PARAM_SYNC_COMPRESS             (1UL << 21)
3311#define OG_REST_PARAM_SYNC_CLEANUP              (1UL << 22)
3312#define OG_REST_PARAM_SYNC_CACHE                (1UL << 23)
3313#define OG_REST_PARAM_SYNC_CLEANUP_CACHE        (1UL << 24)
3314#define OG_REST_PARAM_SYNC_REMOVE_DST           (1UL << 25)
3315#define OG_REST_PARAM_SYNC_DIFF_ID              (1UL << 26)
3316#define OG_REST_PARAM_SYNC_DIFF_NAME            (1UL << 27)
3317#define OG_REST_PARAM_SYNC_PATH                 (1UL << 28)
3318#define OG_REST_PARAM_SYNC_METHOD               (1UL << 29)
[ffd2965]3319#define OG_REST_PARAM_ECHO                      (1UL << 30)
[54ecdbb]3320
3321static bool og_msg_params_validate(const struct og_msg_params *params,
3322                                   const uint64_t flags)
3323{
3324        return (params->flags & flags) == flags;
3325}
3326
[95e6520]3327static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
3328{
3329        unsigned int i;
3330        json_t *k;
3331
3332        if (json_typeof(element) != JSON_ARRAY)
3333                return -1;
3334
3335        for (i = 0; i < json_array_size(element); i++) {
3336                k = json_array_get(element, i);
3337                if (json_typeof(k) != JSON_STRING)
3338                        return -1;
3339
3340                params->ips_array[params->ips_array_len++] =
3341                        json_string_value(k);
[54ecdbb]3342
[280df58]3343                params->flags |= OG_REST_PARAM_ADDR;
3344        }
[54ecdbb]3345
[95e6520]3346        return 0;
3347}
3348
[c87a1db]3349static int og_json_parse_string(json_t *element, const char **str)
3350{
3351        if (json_typeof(element) != JSON_STRING)
3352                return -1;
3353
3354        *str = json_string_value(element);
3355        return 0;
3356}
3357
[ffd2965]3358static int og_json_parse_bool(json_t *element, bool *value)
3359{
3360        if (json_typeof(element) == JSON_TRUE)
3361                *value = true;
3362        else if (json_typeof(element) == JSON_FALSE)
3363                *value = false;
3364        else
3365                return -1;
3366
3367        return 0;
3368}
3369
[82a1d5a]3370static int og_json_parse_sync_params(json_t *element,
3371                                     struct og_msg_params *params)
[01e77f4]3372{
3373        const char *key;
3374        json_t *value;
3375        int err = 0;
3376
3377        json_object_foreach(element, key, value) {
[82a1d5a]3378                if (!strcmp(key, "sync")) {
3379                        err = og_json_parse_string(value, &params->sync_setup.sync);
3380                        params->flags |= OG_REST_PARAM_SYNC_SYNC;
3381                } else if (!strcmp(key, "diff")) {
3382                        err = og_json_parse_string(value, &params->sync_setup.diff);
3383                        params->flags |= OG_REST_PARAM_SYNC_DIFF;
3384                } else if (!strcmp(key, "remove")) {
3385                        err = og_json_parse_string(value, &params->sync_setup.remove);
3386                        params->flags |= OG_REST_PARAM_SYNC_REMOVE;
3387                } else if (!strcmp(key, "compress")) {
3388                        err = og_json_parse_string(value, &params->sync_setup.compress);
3389                        params->flags |= OG_REST_PARAM_SYNC_COMPRESS;
3390                } else if (!strcmp(key, "cleanup")) {
3391                        err = og_json_parse_string(value, &params->sync_setup.cleanup);
3392                        params->flags |= OG_REST_PARAM_SYNC_CLEANUP;
3393                } else if (!strcmp(key, "cache")) {
3394                        err = og_json_parse_string(value, &params->sync_setup.cache);
3395                        params->flags |= OG_REST_PARAM_SYNC_CACHE;
3396                } else if (!strcmp(key, "cleanup_cache")) {
3397                        err = og_json_parse_string(value, &params->sync_setup.cleanup_cache);
3398                        params->flags |= OG_REST_PARAM_SYNC_CLEANUP_CACHE;
3399                } else if (!strcmp(key, "remove_dst")) {
3400                        err = og_json_parse_string(value, &params->sync_setup.remove_dst);
3401                        params->flags |= OG_REST_PARAM_SYNC_REMOVE_DST;
3402                } else if (!strcmp(key, "diff_id")) {
3403                        err = og_json_parse_string(value, &params->sync_setup.diff_id);
3404                        params->flags |= OG_REST_PARAM_SYNC_DIFF_ID;
3405                } else if (!strcmp(key, "diff_name")) {
3406                        err = og_json_parse_string(value, &params->sync_setup.diff_name);
3407                        params->flags |= OG_REST_PARAM_SYNC_DIFF_NAME;
3408                } else if (!strcmp(key, "path")) {
3409                        err = og_json_parse_string(value, &params->sync_setup.path);
3410                        params->flags |= OG_REST_PARAM_SYNC_PATH;
3411                } else if (!strcmp(key, "method")) {
3412                        err = og_json_parse_string(value, &params->sync_setup.method);
3413                        params->flags |= OG_REST_PARAM_SYNC_METHOD;
3414                }
[01e77f4]3415
3416                if (err != 0)
3417                        return err;
3418        }
3419        return err;
3420}
3421
[3bc3b45]3422#define OG_PARAM_PART_NUMBER                    (1UL << 0)
3423#define OG_PARAM_PART_CODE                      (1UL << 1)
3424#define OG_PARAM_PART_FILESYSTEM                (1UL << 2)
3425#define OG_PARAM_PART_SIZE                      (1UL << 3)
3426#define OG_PARAM_PART_FORMAT                    (1UL << 4)
3427
3428static int og_json_parse_partition(json_t *element,
3429                                   struct og_msg_params *params,
3430                                   unsigned int i)
[e3af7ee]3431{
[3bc3b45]3432        struct og_partition *part = &params->partition_setup[i];
3433        uint64_t flags = 0UL;
[e3af7ee]3434        const char *key;
3435        json_t *value;
3436        int err = 0;
3437
3438        json_object_foreach(element, key, value) {
[3bc3b45]3439                if (!strcmp(key, "partition")) {
[e3af7ee]3440                        err = og_json_parse_string(value, &part->number);
[3bc3b45]3441                        flags |= OG_PARAM_PART_NUMBER;
3442                } else if (!strcmp(key, "code")) {
[e3af7ee]3443                        err = og_json_parse_string(value, &part->code);
[3bc3b45]3444                        flags |= OG_PARAM_PART_CODE;
3445                } else if (!strcmp(key, "filesystem")) {
[e3af7ee]3446                        err = og_json_parse_string(value, &part->filesystem);
[3bc3b45]3447                        flags |= OG_PARAM_PART_FILESYSTEM;
3448                } else if (!strcmp(key, "size")) {
[e3af7ee]3449                        err = og_json_parse_string(value, &part->size);
[3bc3b45]3450                        flags |= OG_PARAM_PART_SIZE;
3451                } else if (!strcmp(key, "format")) {
[e3af7ee]3452                        err = og_json_parse_string(value, &part->format);
[3bc3b45]3453                        flags |= OG_PARAM_PART_FORMAT;
3454                }
[e3af7ee]3455
3456                if (err < 0)
3457                        return err;
3458        }
[3bc3b45]3459
3460        if (flags != (OG_PARAM_PART_NUMBER |
3461                      OG_PARAM_PART_CODE |
3462                      OG_PARAM_PART_FILESYSTEM |
3463                      OG_PARAM_PART_SIZE |
3464                      OG_PARAM_PART_FORMAT))
3465                return -1;
3466
3467        params->flags |= (OG_REST_PARAM_PART_0 << i);
3468
[e3af7ee]3469        return err;
[dbcc83d]3470}
3471
[3bc3b45]3472static int og_json_parse_partition_setup(json_t *element,
3473                                         struct og_msg_params *params)
[dbcc83d]3474{
3475        unsigned int i;
3476        json_t *k;
3477
3478        if (json_typeof(element) != JSON_ARRAY)
3479                return -1;
3480
3481        for (i = 0; i < json_array_size(element) && i < OG_PARTITION_MAX; ++i) {
3482                k = json_array_get(element, i);
3483
3484                if (json_typeof(k) != JSON_OBJECT)
3485                        return -1;
3486
[3bc3b45]3487                if (og_json_parse_partition(k, params, i) != 0)
[e3af7ee]3488                        return -1;
[dbcc83d]3489        }
3490        return 0;
3491}
3492
[40023ff]3493static int og_cmd_legacy_send(struct og_msg_params *params, const char *cmd,
3494                              const char *state)
[95e6520]3495{
3496        char buf[4096] = {};
3497        int len, err = 0;
3498        TRAMA *msg;
3499
[40023ff]3500        len = snprintf(buf, sizeof(buf), "nfn=%s\r", cmd);
[95e6520]3501
3502        msg = og_msg_alloc(buf, len);
3503        if (!msg)
3504                return -1;
3505
3506        if (!og_send_cmd((char **)params->ips_array, params->ips_array_len,
[40023ff]3507                         state, msg))
[95e6520]3508                err = -1;
3509
3510        og_msg_free(msg);
3511
3512        return err;
3513}
3514
3515static int og_cmd_post_clients(json_t *element, struct og_msg_params *params)
3516{
3517        const char *key;
3518        json_t *value;
3519        int err = 0;
3520
3521        if (json_typeof(element) != JSON_OBJECT)
3522                return -1;
3523
3524        json_object_foreach(element, key, value) {
3525                if (!strcmp(key, "clients"))
3526                        err = og_json_parse_clients(value, params);
3527
3528                if (err < 0)
3529                        break;
3530        }
3531
[54ecdbb]3532        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
3533                return -1;
3534
[40023ff]3535        return og_cmd_legacy_send(params, "Sondeo", CLIENTE_APAGADO);
[95e6520]3536}
3537
[7b6fcdb]3538struct og_buffer {
3539        char    *data;
3540        int     len;
3541};
3542
3543static int og_json_dump_clients(const char *buffer, size_t size, void *data)
3544{
3545        struct og_buffer *og_buffer = (struct og_buffer *)data;
3546
3547        memcpy(og_buffer->data + og_buffer->len, buffer, size);
3548        og_buffer->len += size;
3549
3550        return 0;
3551}
3552
3553static int og_cmd_get_clients(json_t *element, struct og_msg_params *params,
3554                              char *buffer_reply)
3555{
3556        json_t *root, *array, *addr, *state, *object;
3557        struct og_buffer og_buffer = {
3558                .data   = buffer_reply,
3559        };
3560        int i;
3561
3562        array = json_array();
3563        if (!array)
3564                return -1;
3565
3566        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
3567                if (tbsockets[i].ip[0] == '\0')
3568                        continue;
3569
3570                object = json_object();
3571                if (!object) {
3572                        json_decref(array);
3573                        return -1;
3574                }
3575                addr = json_string(tbsockets[i].ip);
3576                if (!addr) {
3577                        json_decref(object);
3578                        json_decref(array);
3579                        return -1;
3580                }
3581                json_object_set_new(object, "addr", addr);
3582
3583                state = json_string(tbsockets[i].estado);
3584                if (!state) {
3585                        json_decref(object);
3586                        json_decref(array);
3587                        return -1;
3588                }
3589                json_object_set_new(object, "state", state);
3590
3591                json_array_append_new(array, object);
3592        }
3593        root = json_pack("{s:o}", "clients", array);
3594        if (!root) {
3595                json_decref(array);
3596                return -1;
3597        }
3598
[7e6ba45]3599        json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
[7b6fcdb]3600        json_decref(root);
3601
3602        return 0;
3603}
3604
[5797e0b]3605static int og_json_parse_target(json_t *element, struct og_msg_params *params)
3606{
3607        const char *key;
3608        json_t *value;
3609
3610        if (json_typeof(element) != JSON_OBJECT) {
3611                return -1;
3612        }
3613
3614        json_object_foreach(element, key, value) {
3615                if (!strcmp(key, "addr")) {
3616                        if (json_typeof(value) != JSON_STRING)
3617                                return -1;
3618
3619                        params->ips_array[params->ips_array_len] =
3620                                json_string_value(value);
[ec5fe70]3621
3622                        params->flags |= OG_REST_PARAM_ADDR;
[5797e0b]3623                } else if (!strcmp(key, "mac")) {
3624                        if (json_typeof(value) != JSON_STRING)
3625                                return -1;
3626
3627                        params->mac_array[params->ips_array_len] =
3628                                json_string_value(value);
[ec5fe70]3629
3630                        params->flags |= OG_REST_PARAM_MAC;
[5797e0b]3631                }
3632        }
3633
3634        return 0;
3635}
3636
3637static int og_json_parse_targets(json_t *element, struct og_msg_params *params)
3638{
3639        unsigned int i;
3640        json_t *k;
3641        int err;
3642
3643        if (json_typeof(element) != JSON_ARRAY)
3644                return -1;
3645
3646        for (i = 0; i < json_array_size(element); i++) {
3647                k = json_array_get(element, i);
3648
3649                if (json_typeof(k) != JSON_OBJECT)
3650                        return -1;
3651
3652                err = og_json_parse_target(k, params);
3653                if (err < 0)
3654                        return err;
3655
3656                params->ips_array_len++;
3657        }
3658        return 0;
3659}
3660
3661static int og_json_parse_type(json_t *element, struct og_msg_params *params)
3662{
3663        const char *type;
3664
3665        if (json_typeof(element) != JSON_STRING)
3666                return -1;
3667
3668        params->wol_type = json_string_value(element);
3669
3670        type = json_string_value(element);
3671        if (!strcmp(type, "unicast"))
3672                params->wol_type = "2";
3673        else if (!strcmp(type, "broadcast"))
3674                params->wol_type = "1";
3675
[ec5fe70]3676        params->flags |= OG_REST_PARAM_WOL_TYPE;
3677
[5797e0b]3678        return 0;
3679}
3680
3681static int og_cmd_wol(json_t *element, struct og_msg_params *params)
3682{
3683        const char *key;
3684        json_t *value;
3685        int err = 0;
3686
3687        if (json_typeof(element) != JSON_OBJECT)
3688                return -1;
3689
3690        json_object_foreach(element, key, value) {
3691                if (!strcmp(key, "clients")) {
3692                        err = og_json_parse_targets(value, params);
3693                } else if (!strcmp(key, "type")) {
3694                        err = og_json_parse_type(value, params);
3695                }
3696
3697                if (err < 0)
3698                        break;
3699        }
3700
[ec5fe70]3701        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
3702                                            OG_REST_PARAM_MAC |
3703                                            OG_REST_PARAM_WOL_TYPE))
3704                return -1;
3705
[5797e0b]3706        if (!Levanta((char **)params->ips_array, (char **)params->mac_array,
3707                     params->ips_array_len, (char *)params->wol_type))
3708                return -1;
3709
3710        return 0;
3711}
3712
[7e4e5b5]3713static int og_json_parse_run(json_t *element, struct og_msg_params *params)
3714{
3715        if (json_typeof(element) != JSON_STRING)
3716                return -1;
3717
3718        snprintf(params->run_cmd, sizeof(params->run_cmd), "%s",
3719                 json_string_value(element));
3720
[b403c7a]3721        params->flags |= OG_REST_PARAM_RUN_CMD;
3722
[7e4e5b5]3723        return 0;
3724}
3725
3726static int og_cmd_run_post(json_t *element, struct og_msg_params *params)
3727{
3728        char buf[4096] = {}, iph[4096] = {};
3729        int err = 0, len;
3730        const char *key;
3731        unsigned int i;
3732        json_t *value;
3733        TRAMA *msg;
3734
3735        if (json_typeof(element) != JSON_OBJECT)
3736                return -1;
3737
3738        json_object_foreach(element, key, value) {
3739                if (!strcmp(key, "clients"))
3740                        err = og_json_parse_clients(value, params);
[ffd2965]3741                else if (!strcmp(key, "run"))
[7e4e5b5]3742                        err = og_json_parse_run(value, params);
[ffd2965]3743                else if (!strcmp(key, "echo")) {
3744                        err = og_json_parse_bool(value, &params->echo);
3745                        params->flags |= OG_REST_PARAM_ECHO;
3746                }
[7e4e5b5]3747
3748                if (err < 0)
3749                        break;
3750        }
3751
[b403c7a]3752        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
[ffd2965]3753                                            OG_REST_PARAM_RUN_CMD |
3754                                            OG_REST_PARAM_ECHO))
[b403c7a]3755                return -1;
3756
[7e4e5b5]3757        for (i = 0; i < params->ips_array_len; i++) {
3758                len = snprintf(iph + strlen(iph), sizeof(iph), "%s;",
3759                               params->ips_array[i]);
3760        }
[ffd2965]3761
3762        if (params->echo) {
3763                len = snprintf(buf, sizeof(buf),
3764                               "nfn=ConsolaRemota\riph=%s\rscp=%s\r",
3765                               iph, params->run_cmd);
3766        } else {
3767                len = snprintf(buf, sizeof(buf),
3768                               "nfn=EjecutarScript\riph=%s\rscp=%s\r",
3769                               iph, params->run_cmd);
3770        }
[7e4e5b5]3771
3772        msg = og_msg_alloc(buf, len);
3773        if (!msg)
3774                return -1;
3775
3776        if (!og_send_cmd((char **)params->ips_array, params->ips_array_len,
3777                         CLIENTE_OCUPADO, msg))
3778                err = -1;
3779
3780        og_msg_free(msg);
3781
3782        if (err < 0)
3783                return err;
3784
3785        for (i = 0; i < params->ips_array_len; i++) {
3786                char filename[4096];
3787                FILE *f;
3788
3789                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
3790                f = fopen(filename, "wt");
3791                fclose(f);
3792        }
3793
3794        return 0;
3795}
3796
[c6020f2]3797static int og_cmd_run_get(json_t *element, struct og_msg_params *params,
3798                          char *buffer_reply)
3799{
3800        struct og_buffer og_buffer = {
3801                .data   = buffer_reply,
3802        };
3803        json_t *root, *value, *array;
3804        const char *key;
3805        unsigned int i;
3806        int err = 0;
3807
3808        if (json_typeof(element) != JSON_OBJECT)
3809                return -1;
3810
3811        json_object_foreach(element, key, value) {
3812                if (!strcmp(key, "clients"))
3813                        err = og_json_parse_clients(value, params);
3814
3815                if (err < 0)
3816                        return err;
3817        }
3818
[61059e1]3819        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
3820                return -1;
3821
[c6020f2]3822        array = json_array();
3823        if (!array)
3824                return -1;
3825
3826        for (i = 0; i < params->ips_array_len; i++) {
3827                json_t *object, *output, *addr;
3828                char data[4096] = {};
3829                char filename[4096];
3830                int fd, numbytes;
3831
3832                sprintf(filename, "/tmp/_Seconsola_%s", params->ips_array[i]);
3833
3834                fd = open(filename, O_RDONLY);
3835                if (!fd)
3836                        return -1;
3837
3838                numbytes = read(fd, data, sizeof(data));
3839                if (numbytes < 0) {
3840                        close(fd);
3841                        return -1;
3842                }
3843                data[sizeof(data) - 1] = '\0';
3844                close(fd);
3845
3846                object = json_object();
3847                if (!object) {
3848                        json_decref(array);
3849                        return -1;
3850                }
3851                addr = json_string(params->ips_array[i]);
3852                if (!addr) {
3853                        json_decref(object);
3854                        json_decref(array);
3855                        return -1;
3856                }
3857                json_object_set_new(object, "addr", addr);
3858
3859                output = json_string(data);
3860                if (!output) {
3861                        json_decref(object);
3862                        json_decref(array);
3863                        return -1;
3864                }
3865                json_object_set_new(object, "output", output);
3866
3867                json_array_append_new(array, object);
3868        }
3869
3870        root = json_pack("{s:o}", "clients", array);
3871        if (!root)
3872                return -1;
3873
[7e6ba45]3874        json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
[c6020f2]3875        json_decref(root);
3876
3877        return 0;
3878}
3879
[7ab5f0c]3880static int og_cmd_session(json_t *element, struct og_msg_params *params)
3881{
3882        char buf[4096], iph[4096];
3883        int err = 0, len;
3884        const char *key;
3885        unsigned int i;
3886        json_t *value;
3887        TRAMA *msg;
3888
3889        if (json_typeof(element) != JSON_OBJECT)
3890                return -1;
3891
3892        json_object_foreach(element, key, value) {
[8901505]3893                if (!strcmp(key, "clients")) {
[7ab5f0c]3894                        err = og_json_parse_clients(value, params);
[8901505]3895                } else if (!strcmp(key, "disk")) {
[c87a1db]3896                        err = og_json_parse_string(value, &params->disk);
[8901505]3897                        params->flags |= OG_REST_PARAM_DISK;
3898                } else if (!strcmp(key, "partition")) {
[c87a1db]3899                        err = og_json_parse_string(value, &params->partition);
[8901505]3900                        params->flags |= OG_REST_PARAM_PARTITION;
3901                }
[7ab5f0c]3902
3903                if (err < 0)
3904                        return err;
3905        }
3906
[8901505]3907        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
3908                                            OG_REST_PARAM_DISK |
3909                                            OG_REST_PARAM_PARTITION))
3910                return -1;
3911
[7ab5f0c]3912        for (i = 0; i < params->ips_array_len; i++) {
3913                snprintf(iph + strlen(iph), sizeof(iph), "%s;",
3914                         params->ips_array[i]);
3915        }
3916        len = snprintf(buf, sizeof(buf),
3917                       "nfn=IniciarSesion\riph=%s\rdsk=%s\rpar=%s\r",
3918                       iph, params->disk, params->partition);
3919
3920        msg = og_msg_alloc(buf, len);
3921        if (!msg)
3922                return -1;
3923
3924        if (!og_send_cmd((char **)params->ips_array, params->ips_array_len,
3925                         CLIENTE_APAGADO, msg))
3926                err = -1;
3927
3928        og_msg_free(msg);
3929
3930        return 0;
3931}
3932
[23fed47]3933static int og_cmd_poweroff(json_t *element, struct og_msg_params *params)
3934{
3935        const char *key;
3936        json_t *value;
3937        int err = 0;
3938
3939        if (json_typeof(element) != JSON_OBJECT)
3940                return -1;
3941
3942        json_object_foreach(element, key, value) {
3943                if (!strcmp(key, "clients"))
3944                        err = og_json_parse_clients(value, params);
3945
3946                if (err < 0)
3947                        break;
3948        }
3949
[acf9cdf]3950        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
3951                return -1;
3952
[23fed47]3953        return og_cmd_legacy_send(params, "Apagar", CLIENTE_OCUPADO);
3954}
3955
[17f55b4]3956static int og_cmd_refresh(json_t *element, struct og_msg_params *params)
3957{
3958        const char *key;
3959        json_t *value;
3960        int err = 0;
3961
3962        if (json_typeof(element) != JSON_OBJECT)
3963                return -1;
3964
3965        json_object_foreach(element, key, value) {
3966                if (!strcmp(key, "clients"))
3967                        err = og_json_parse_clients(value, params);
3968
3969                if (err < 0)
3970                        break;
3971        }
3972
[93028bd]3973        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
3974                return -1;
3975
[17f55b4]3976        return og_cmd_legacy_send(params, "Actualizar", CLIENTE_APAGADO);
3977}
3978
[5f0191d]3979static int og_cmd_reboot(json_t *element, struct og_msg_params *params)
3980{
3981        const char *key;
3982        json_t *value;
3983        int err = 0;
3984
3985        if (json_typeof(element) != JSON_OBJECT)
3986                return -1;
3987
3988        json_object_foreach(element, key, value) {
3989                if (!strcmp(key, "clients"))
3990                        err = og_json_parse_clients(value, params);
3991
3992                if (err < 0)
3993                        break;
3994        }
3995
[0a41d5d]3996        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
3997                return -1;
3998
[5f0191d]3999        return og_cmd_legacy_send(params, "Reiniciar", CLIENTE_OCUPADO);
4000}
4001
[1e6c889]4002static int og_cmd_stop(json_t *element, struct og_msg_params *params)
4003{
4004        const char *key;
4005        json_t *value;
4006        int err = 0;
4007
4008        if (json_typeof(element) != JSON_OBJECT)
4009                return -1;
4010
4011        json_object_foreach(element, key, value) {
4012                if (!strcmp(key, "clients"))
4013                        err = og_json_parse_clients(value, params);
4014
4015                if (err < 0)
4016                        break;
4017        }
4018
[bc1b958]4019        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
4020                return -1;
4021
[1e6c889]4022        return og_cmd_legacy_send(params, "Purgar", CLIENTE_APAGADO);
4023}
4024
[6b30dbc]4025static int og_cmd_hardware(json_t *element, struct og_msg_params *params)
4026{
4027        const char *key;
4028        json_t *value;
4029        int err = 0;
4030
4031        if (json_typeof(element) != JSON_OBJECT)
4032                return -1;
4033
4034        json_object_foreach(element, key, value) {
4035                if (!strcmp(key, "clients"))
4036                        err = og_json_parse_clients(value, params);
4037
4038                if (err < 0)
4039                        break;
4040        }
4041
[7803e13]4042        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
4043                return -1;
4044
[6b30dbc]4045        return og_cmd_legacy_send(params, "InventarioHardware",
4046                                  CLIENTE_OCUPADO);
4047}
4048
[b4a9fdd]4049static int og_cmd_software(json_t *element, struct og_msg_params *params)
4050{
[61bbcd9]4051        char buf[4096] = {};
4052        int err = 0, len;
[b4a9fdd]4053        const char *key;
4054        json_t *value;
[61bbcd9]4055        TRAMA *msg;
[b4a9fdd]4056
4057        if (json_typeof(element) != JSON_OBJECT)
4058                return -1;
4059
4060        json_object_foreach(element, key, value) {
4061                if (!strcmp(key, "clients"))
4062                        err = og_json_parse_clients(value, params);
[1a1ecf7]4063                else if (!strcmp(key, "disk")) {
[61bbcd9]4064                        err = og_json_parse_string(value, &params->disk);
[1a1ecf7]4065                        params->flags |= OG_REST_PARAM_DISK;
4066                }
4067                else if (!strcmp(key, "partition")) {
[61bbcd9]4068                        err = og_json_parse_string(value, &params->partition);
[1a1ecf7]4069                        params->flags |= OG_REST_PARAM_PARTITION;
4070                }
[b4a9fdd]4071
4072                if (err < 0)
4073                        break;
4074        }
4075
[1a1ecf7]4076        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4077                                            OG_REST_PARAM_DISK |
4078                                            OG_REST_PARAM_PARTITION))
4079                return -1;
4080
[61bbcd9]4081        len = snprintf(buf, sizeof(buf),
4082                       "nfn=InventarioSoftware\rdsk=%s\rpar=%s\r",
4083                       params->disk, params->partition);
4084
4085        msg = og_msg_alloc(buf, len);
4086        if (!msg)
4087                return -1;
4088
4089        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4090                    CLIENTE_OCUPADO, msg);
4091
4092        og_msg_free(msg);
4093
4094        return 0;
[b4a9fdd]4095}
4096
[1a8ada1]4097static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
4098{
4099        char buf[4096] = {};
4100        int err = 0, len;
4101        const char *key;
4102        json_t *value;
4103        TRAMA *msg;
4104
4105        if (json_typeof(element) != JSON_OBJECT)
4106                return -1;
4107
4108        json_object_foreach(element, key, value) {
[abe2a88]4109                if (!strcmp(key, "disk")) {
[c87a1db]4110                        err = og_json_parse_string(value, &params->disk);
[abe2a88]4111                        params->flags |= OG_REST_PARAM_DISK;
4112                } else if (!strcmp(key, "partition")) {
[c87a1db]4113                        err = og_json_parse_string(value, &params->partition);
[abe2a88]4114                        params->flags |= OG_REST_PARAM_PARTITION;
4115                } else if (!strcmp(key, "name")) {
[c87a1db]4116                        err = og_json_parse_string(value, &params->name);
[abe2a88]4117                        params->flags |= OG_REST_PARAM_NAME;
4118                } else if (!strcmp(key, "repository")) {
[c87a1db]4119                        err = og_json_parse_string(value, &params->repository);
[abe2a88]4120                        params->flags |= OG_REST_PARAM_REPO;
4121                } else if (!strcmp(key, "clients")) {
[1a8ada1]4122                        err = og_json_parse_clients(value, params);
[abe2a88]4123                } else if (!strcmp(key, "id")) {
[c87a1db]4124                        err = og_json_parse_string(value, &params->id);
[abe2a88]4125                        params->flags |= OG_REST_PARAM_ID;
4126                } else if (!strcmp(key, "code")) {
[c87a1db]4127                        err = og_json_parse_string(value, &params->code);
[abe2a88]4128                        params->flags |= OG_REST_PARAM_CODE;
4129                }
[1a8ada1]4130
4131                if (err < 0)
4132                        break;
4133        }
4134
[abe2a88]4135        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4136                                            OG_REST_PARAM_DISK |
4137                                            OG_REST_PARAM_PARTITION |
4138                                            OG_REST_PARAM_CODE |
4139                                            OG_REST_PARAM_ID |
4140                                            OG_REST_PARAM_NAME |
4141                                            OG_REST_PARAM_REPO))
4142                return -1;
4143
[1a8ada1]4144        len = snprintf(buf, sizeof(buf),
4145                        "nfn=CrearImagen\rdsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s\r",
4146                        params->disk, params->partition, params->code,
4147                        params->id, params->name, params->repository);
4148
4149        msg = og_msg_alloc(buf, len);
4150        if (!msg)
4151                return -1;
4152
4153        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4154                    CLIENTE_OCUPADO, msg);
4155
4156        og_msg_free(msg);
4157
4158        return 0;
4159}
4160
[1dde02e]4161static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
4162{
4163        char buf[4096] = {};
4164        int err = 0, len;
4165        const char *key;
4166        json_t *value;
4167        TRAMA *msg;
4168
4169        if (json_typeof(element) != JSON_OBJECT)
4170                return -1;
4171
4172        json_object_foreach(element, key, value) {
[ec4189b]4173                if (!strcmp(key, "disk")) {
[1dde02e]4174                        err = og_json_parse_string(value, &params->disk);
[ec4189b]4175                        params->flags |= OG_REST_PARAM_DISK;
4176                } else if (!strcmp(key, "partition")) {
[1dde02e]4177                        err = og_json_parse_string(value, &params->partition);
[ec4189b]4178                        params->flags |= OG_REST_PARAM_PARTITION;
4179                } else if (!strcmp(key, "name")) {
[1dde02e]4180                        err = og_json_parse_string(value, &params->name);
[ec4189b]4181                        params->flags |= OG_REST_PARAM_NAME;
4182                } else if (!strcmp(key, "repository")) {
[1dde02e]4183                        err = og_json_parse_string(value, &params->repository);
[ec4189b]4184                        params->flags |= OG_REST_PARAM_REPO;
4185                } else if (!strcmp(key, "clients")) {
[1dde02e]4186                        err = og_json_parse_clients(value, params);
[ec4189b]4187                } else if (!strcmp(key, "type")) {
[1dde02e]4188                        err = og_json_parse_string(value, &params->type);
[ec4189b]4189                        params->flags |= OG_REST_PARAM_TYPE;
4190                } else if (!strcmp(key, "profile")) {
[1dde02e]4191                        err = og_json_parse_string(value, &params->profile);
[ec4189b]4192                        params->flags |= OG_REST_PARAM_PROFILE;
4193                } else if (!strcmp(key, "id")) {
[1dde02e]4194                        err = og_json_parse_string(value, &params->id);
[ec4189b]4195                        params->flags |= OG_REST_PARAM_ID;
4196                }
[1dde02e]4197
4198                if (err < 0)
4199                        break;
4200        }
4201
[ec4189b]4202        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4203                                            OG_REST_PARAM_DISK |
4204                                            OG_REST_PARAM_PARTITION |
4205                                            OG_REST_PARAM_NAME |
4206                                            OG_REST_PARAM_REPO |
4207                                            OG_REST_PARAM_TYPE |
4208                                            OG_REST_PARAM_PROFILE |
4209                                            OG_REST_PARAM_ID))
4210                return -1;
4211
[1dde02e]4212        len = snprintf(buf, sizeof(buf),
4213                       "nfn=RestaurarImagen\ridi=%s\rdsk=%s\rpar=%s\rifs=%s\r"
4214                       "nci=%s\ripr=%s\rptc=%s\r",
4215                       params->id, params->disk, params->partition,
4216                       params->profile, params->name,
4217                       params->repository, params->type);
4218
4219        msg = og_msg_alloc(buf, len);
4220        if (!msg)
4221                return -1;
4222
4223        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4224                    CLIENTE_OCUPADO, msg);
4225
4226        og_msg_free(msg);
4227
4228        return 0;
4229}
4230
[6c91d14]4231static int og_cmd_setup(json_t *element, struct og_msg_params *params)
[dbcc83d]4232{
4233        char buf[4096] = {};
4234        int err = 0, len;
4235        const char *key;
4236        json_t *value;
4237        TRAMA *msg;
4238
4239        if (json_typeof(element) != JSON_OBJECT)
4240                return -1;
4241
4242        json_object_foreach(element, key, value) {
[3bc3b45]4243                if (!strcmp(key, "clients")) {
[dbcc83d]4244                        err = og_json_parse_clients(value, params);
[3bc3b45]4245                } else if (!strcmp(key, "disk")) {
[dbcc83d]4246                        err = og_json_parse_string(value, &params->disk);
[3bc3b45]4247                        params->flags |= OG_REST_PARAM_DISK;
4248                } else if (!strcmp(key, "cache")) {
[dbcc83d]4249                        err = og_json_parse_string(value, &params->cache);
[3bc3b45]4250                        params->flags |= OG_REST_PARAM_CACHE;
4251                } else if (!strcmp(key, "cache_size")) {
[dbcc83d]4252                        err = og_json_parse_string(value, &params->cache_size);
[3bc3b45]4253                        params->flags |= OG_REST_PARAM_CACHE_SIZE;
4254                } else if (!strcmp(key, "partition_setup")) {
4255                        err = og_json_parse_partition_setup(value, params);
4256                }
[dbcc83d]4257
4258                if (err < 0)
4259                        break;
4260        }
4261
[3bc3b45]4262        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4263                                            OG_REST_PARAM_DISK |
4264                                            OG_REST_PARAM_CACHE |
4265                                            OG_REST_PARAM_CACHE_SIZE |
4266                                            OG_REST_PARAM_PART_0 |
4267                                            OG_REST_PARAM_PART_1 |
4268                                            OG_REST_PARAM_PART_2 |
4269                                            OG_REST_PARAM_PART_3))
4270                return -1;
4271
[dbcc83d]4272        len = snprintf(buf, sizeof(buf),
4273                        "nfn=Configurar\rdsk=%s\rcfg=dis=%s*che=%s*tch=%s!",
4274                        params->disk, params->disk, params->cache, params->cache_size);
4275
4276        for (unsigned int i = 0; i < OG_PARTITION_MAX; ++i) {
[3bc3b45]4277                const struct og_partition *part = &params->partition_setup[i];
[dbcc83d]4278
4279                len += snprintf(buf + strlen(buf), sizeof(buf),
4280                        "par=%s*cpt=%s*sfi=%s*tam=%s*ope=%s%%",
4281                        part->number, part->code, part->filesystem, part->size, part->format);
4282        }
4283
4284        msg = og_msg_alloc(buf, len + 1);
4285        if (!msg)
4286                return -1;
4287
4288        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4289                        CLIENTE_OCUPADO, msg);
4290
4291        og_msg_free(msg);
4292
4293        return 0;
4294}
4295
[2f7e9da]4296static int og_cmd_run_schedule(json_t *element, struct og_msg_params *params)
4297{
4298        const char *key;
4299        json_t *value;
[723f110]4300        int err = 0;
[2f7e9da]4301
4302        json_object_foreach(element, key, value) {
4303                if (!strcmp(key, "clients"))
4304                        err = og_json_parse_clients(value, params);
4305
4306                if (err < 0)
4307                        break;
4308        }
4309
[6066b32]4310        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
4311                return -1;
4312
[723f110]4313        og_cmd_legacy_send(params, "EjecutaComandosPendientes", CLIENTE_OCUPADO);
[2f7e9da]4314
4315        return 0;
4316}
4317
[01e77f4]4318static int og_cmd_create_basic_image(json_t *element, struct og_msg_params *params)
4319{
4320        char buf[4096] = {};
4321        int err = 0, len;
4322        const char *key;
4323        json_t *value;
4324        TRAMA *msg;
4325
4326        if (json_typeof(element) != JSON_OBJECT)
4327                return -1;
4328
4329        json_object_foreach(element, key, value) {
[82a1d5a]4330                if (!strcmp(key, "clients")) {
[01e77f4]4331                        err = og_json_parse_clients(value, params);
[82a1d5a]4332                } else if (!strcmp(key, "disk")) {
[01e77f4]4333                        err = og_json_parse_string(value, &params->disk);
[82a1d5a]4334                        params->flags |= OG_REST_PARAM_DISK;
4335                } else if (!strcmp(key, "partition")) {
[01e77f4]4336                        err = og_json_parse_string(value, &params->partition);
[82a1d5a]4337                        params->flags |= OG_REST_PARAM_PARTITION;
4338                } else if (!strcmp(key, "code")) {
[01e77f4]4339                        err = og_json_parse_string(value, &params->code);
[82a1d5a]4340                        params->flags |= OG_REST_PARAM_CODE;
4341                } else if (!strcmp(key, "id")) {
[01e77f4]4342                        err = og_json_parse_string(value, &params->id);
[82a1d5a]4343                        params->flags |= OG_REST_PARAM_ID;
4344                } else if (!strcmp(key, "name")) {
[01e77f4]4345                        err = og_json_parse_string(value, &params->name);
[82a1d5a]4346                        params->flags |= OG_REST_PARAM_NAME;
4347                } else if (!strcmp(key, "repository")) {
[01e77f4]4348                        err = og_json_parse_string(value, &params->repository);
[82a1d5a]4349                        params->flags |= OG_REST_PARAM_REPO;
4350                } else if (!strcmp(key, "sync_params")) {
4351                        err = og_json_parse_sync_params(value, params);
4352                }
[01e77f4]4353
4354                if (err < 0)
4355                        break;
4356        }
4357
[82a1d5a]4358        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4359                                            OG_REST_PARAM_DISK |
4360                                            OG_REST_PARAM_PARTITION |
4361                                            OG_REST_PARAM_CODE |
4362                                            OG_REST_PARAM_ID |
4363                                            OG_REST_PARAM_NAME |
4364                                            OG_REST_PARAM_REPO |
4365                                            OG_REST_PARAM_SYNC_SYNC |
4366                                            OG_REST_PARAM_SYNC_DIFF |
4367                                            OG_REST_PARAM_SYNC_REMOVE |
4368                                            OG_REST_PARAM_SYNC_COMPRESS |
4369                                            OG_REST_PARAM_SYNC_CLEANUP |
4370                                            OG_REST_PARAM_SYNC_CACHE |
4371                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
4372                                            OG_REST_PARAM_SYNC_REMOVE_DST))
4373                return -1;
4374
[01e77f4]4375        len = snprintf(buf, sizeof(buf),
4376                       "nfn=CrearImagenBasica\rdsk=%s\rpar=%s\rcpt=%s\ridi=%s\r"
4377                       "nci=%s\ripr=%s\rrti=\rmsy=%s\rwhl=%s\reli=%s\rcmp=%s\rbpi=%s\r"
4378                       "cpc=%s\rbpc=%s\rnba=%s\r",
4379                       params->disk, params->partition, params->code, params->id,
4380                       params->name, params->repository, params->sync_setup.sync,
4381                       params->sync_setup.diff, params->sync_setup.remove,
4382                       params->sync_setup.compress, params->sync_setup.cleanup,
4383                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
4384                       params->sync_setup.remove_dst);
4385
4386        msg = og_msg_alloc(buf, len);
4387        if (!msg)
4388                return -1;
4389
4390        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4391                    CLIENTE_OCUPADO, msg);
4392
4393        og_msg_free(msg);
4394
4395        return 0;
4396}
4397
[43c7da8]4398static int og_cmd_create_incremental_image(json_t *element, struct og_msg_params *params)
4399{
4400        char buf[4096] = {};
4401        int err = 0, len;
4402        const char *key;
4403        json_t *value;
4404        TRAMA *msg;
4405
4406        if (json_typeof(element) != JSON_OBJECT)
4407                return -1;
4408
4409        json_object_foreach(element, key, value) {
4410                if (!strcmp(key, "clients"))
4411                        err = og_json_parse_clients(value, params);
[6a0e5fa]4412                else if (!strcmp(key, "disk")) {
[43c7da8]4413                        err = og_json_parse_string(value, &params->disk);
[6a0e5fa]4414                        params->flags |= OG_REST_PARAM_DISK;
4415                } else if (!strcmp(key, "partition")) {
[43c7da8]4416                        err = og_json_parse_string(value, &params->partition);
[6a0e5fa]4417                        params->flags |= OG_REST_PARAM_PARTITION;
4418                } else if (!strcmp(key, "id")) {
[43c7da8]4419                        err = og_json_parse_string(value, &params->id);
[6a0e5fa]4420                        params->flags |= OG_REST_PARAM_ID;
4421                } else if (!strcmp(key, "name")) {
[43c7da8]4422                        err = og_json_parse_string(value, &params->name);
[6a0e5fa]4423                        params->flags |= OG_REST_PARAM_NAME;
4424                } else if (!strcmp(key, "repository")) {
[43c7da8]4425                        err = og_json_parse_string(value, &params->repository);
[6a0e5fa]4426                        params->flags |= OG_REST_PARAM_REPO;
4427                } else if (!strcmp(key, "sync_params")) {
4428                        err = og_json_parse_sync_params(value, params);
4429                }
[43c7da8]4430
4431                if (err < 0)
4432                        break;
4433        }
4434
[6a0e5fa]4435        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4436                                            OG_REST_PARAM_DISK |
4437                                            OG_REST_PARAM_PARTITION |
4438                                            OG_REST_PARAM_ID |
4439                                            OG_REST_PARAM_NAME |
4440                                            OG_REST_PARAM_REPO |
4441                                            OG_REST_PARAM_SYNC_SYNC |
4442                                            OG_REST_PARAM_SYNC_PATH |
4443                                            OG_REST_PARAM_SYNC_DIFF |
4444                                            OG_REST_PARAM_SYNC_DIFF_ID |
4445                                            OG_REST_PARAM_SYNC_DIFF_NAME |
4446                                            OG_REST_PARAM_SYNC_REMOVE |
4447                                            OG_REST_PARAM_SYNC_COMPRESS |
4448                                            OG_REST_PARAM_SYNC_CLEANUP |
4449                                            OG_REST_PARAM_SYNC_CACHE |
4450                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
4451                                            OG_REST_PARAM_SYNC_REMOVE_DST))
4452                return -1;
4453
[43c7da8]4454        len = snprintf(buf, sizeof(buf),
4455                       "nfn=CrearSoftIncremental\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
4456                       "rti=%s\ripr=%s\ridf=%s\rncf=%s\rmsy=%s\rwhl=%s\reli=%s\rcmp=%s\r"
4457                       "bpi=%s\rcpc=%s\rbpc=%s\rnba=%s\r",
4458                       params->disk, params->partition, params->id, params->name,
4459                       params->sync_setup.path, params->repository, params->sync_setup.diff_id,
4460                       params->sync_setup.diff_name, params->sync_setup.sync,
4461                       params->sync_setup.diff, params->sync_setup.remove_dst,
4462                       params->sync_setup.compress, params->sync_setup.cleanup,
4463                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
4464                       params->sync_setup.remove_dst);
4465
4466        msg = og_msg_alloc(buf, len);
4467        if (!msg)
4468                return -1;
4469
4470        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4471                    CLIENTE_OCUPADO, msg);
4472
4473        og_msg_free(msg);
4474
4475        return 0;
4476}
4477
[f61fd9a]4478static int og_cmd_restore_basic_image(json_t *element, struct og_msg_params *params)
4479{
4480        char buf[4096] = {};
4481        int err = 0, len;
4482        const char *key;
4483        json_t *value;
4484        TRAMA *msg;
4485
4486        if (json_typeof(element) != JSON_OBJECT)
4487                return -1;
4488
4489        json_object_foreach(element, key, value) {
[f51c245]4490                if (!strcmp(key, "clients")) {
[f61fd9a]4491                        err = og_json_parse_clients(value, params);
[f51c245]4492                } else if (!strcmp(key, "disk")) {
[f61fd9a]4493                        err = og_json_parse_string(value, &params->disk);
[f51c245]4494                        params->flags |= OG_REST_PARAM_DISK;
4495                } else if (!strcmp(key, "partition")) {
[f61fd9a]4496                        err = og_json_parse_string(value, &params->partition);
[f51c245]4497                        params->flags |= OG_REST_PARAM_PARTITION;
4498                } else if (!strcmp(key, "id")) {
[f61fd9a]4499                        err = og_json_parse_string(value, &params->id);
[f51c245]4500                        params->flags |= OG_REST_PARAM_ID;
4501                } else if (!strcmp(key, "name")) {
[f61fd9a]4502                        err = og_json_parse_string(value, &params->name);
[f51c245]4503                        params->flags |= OG_REST_PARAM_NAME;
4504                } else if (!strcmp(key, "repository")) {
[f61fd9a]4505                        err = og_json_parse_string(value, &params->repository);
[f51c245]4506                        params->flags |= OG_REST_PARAM_REPO;
4507                } else if (!strcmp(key, "profile")) {
[f61fd9a]4508                        err = og_json_parse_string(value, &params->profile);
[f51c245]4509                        params->flags |= OG_REST_PARAM_PROFILE;
4510                } else if (!strcmp(key, "type")) {
[f61fd9a]4511                        err = og_json_parse_string(value, &params->type);
[f51c245]4512                        params->flags |= OG_REST_PARAM_TYPE;
4513                } else if (!strcmp(key, "sync_params")) {
4514                        err = og_json_parse_sync_params(value, params);
4515                }
[f61fd9a]4516
4517                if (err < 0)
4518                        break;
4519        }
4520
[f51c245]4521        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4522                                            OG_REST_PARAM_DISK |
4523                                            OG_REST_PARAM_PARTITION |
4524                                            OG_REST_PARAM_ID |
4525                                            OG_REST_PARAM_NAME |
4526                                            OG_REST_PARAM_REPO |
4527                                            OG_REST_PARAM_PROFILE |
4528                                            OG_REST_PARAM_TYPE |
4529                                            OG_REST_PARAM_SYNC_PATH |
4530                                            OG_REST_PARAM_SYNC_METHOD |
4531                                            OG_REST_PARAM_SYNC_SYNC |
4532                                            OG_REST_PARAM_SYNC_DIFF |
4533                                            OG_REST_PARAM_SYNC_REMOVE |
4534                                            OG_REST_PARAM_SYNC_COMPRESS |
4535                                            OG_REST_PARAM_SYNC_CLEANUP |
4536                                            OG_REST_PARAM_SYNC_CACHE |
4537                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
4538                                            OG_REST_PARAM_SYNC_REMOVE_DST))
4539                return -1;
4540
[f61fd9a]4541        len = snprintf(buf, sizeof(buf),
4542                       "nfn=RestaurarImagenBasica\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
4543                           "ipr=%s\rifs=%s\rrti=%s\rmet=%s\rmsy=%s\rtpt=%s\rwhl=%s\r"
4544                           "eli=%s\rcmp=%s\rbpi=%s\rcpc=%s\rbpc=%s\rnba=%s\r",
4545                       params->disk, params->partition, params->id, params->name,
4546                           params->repository, params->profile, params->sync_setup.path,
4547                           params->sync_setup.method, params->sync_setup.sync, params->type,
4548                           params->sync_setup.diff, params->sync_setup.remove,
4549                       params->sync_setup.compress, params->sync_setup.cleanup,
4550                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
4551                       params->sync_setup.remove_dst);
4552
4553        msg = og_msg_alloc(buf, len);
4554        if (!msg)
4555                return -1;
4556
4557        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4558                    CLIENTE_OCUPADO, msg);
4559
4560        og_msg_free(msg);
4561
4562        return 0;
4563}
4564
[d52c6d0]4565static int og_cmd_restore_incremental_image(json_t *element, struct og_msg_params *params)
4566{
4567        char buf[4096] = {};
4568        int err = 0, len;
4569        const char *key;
4570        json_t *value;
4571        TRAMA *msg;
4572
4573        if (json_typeof(element) != JSON_OBJECT)
4574                return -1;
4575
4576        json_object_foreach(element, key, value) {
[4f78553]4577                if (!strcmp(key, "clients")) {
[d52c6d0]4578                        err = og_json_parse_clients(value, params);
[4f78553]4579                } else if (!strcmp(key, "disk")) {
[d52c6d0]4580                        err = og_json_parse_string(value, &params->disk);
[4f78553]4581                        params->flags |= OG_REST_PARAM_DISK;
4582                } else if (!strcmp(key, "partition")) {
[d52c6d0]4583                        err = og_json_parse_string(value, &params->partition);
[4f78553]4584                        params->flags |= OG_REST_PARAM_PARTITION;
4585                } else if (!strcmp(key, "id")) {
[d52c6d0]4586                        err = og_json_parse_string(value, &params->id);
[4f78553]4587                        params->flags |= OG_REST_PARAM_ID;
4588                } else if (!strcmp(key, "name")) {
[d52c6d0]4589                        err = og_json_parse_string(value, &params->name);
[4f78553]4590                        params->flags |= OG_REST_PARAM_NAME;
4591                } else if (!strcmp(key, "repository")) {
[d52c6d0]4592                        err = og_json_parse_string(value, &params->repository);
[4f78553]4593                        params->flags |= OG_REST_PARAM_REPO;
4594                } else if (!strcmp(key, "profile")) {
[d52c6d0]4595                        err = og_json_parse_string(value, &params->profile);
[4f78553]4596                        params->flags |= OG_REST_PARAM_PROFILE;
4597                } else if (!strcmp(key, "type")) {
[d52c6d0]4598                        err = og_json_parse_string(value, &params->type);
[4f78553]4599                        params->flags |= OG_REST_PARAM_TYPE;
4600                } else if (!strcmp(key, "sync_params")) {
4601                        err = og_json_parse_sync_params(value, params);
4602                }
[d52c6d0]4603
4604                if (err < 0)
4605                        break;
4606        }
4607
[4f78553]4608        if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
4609                                            OG_REST_PARAM_DISK |
4610                                            OG_REST_PARAM_PARTITION |
4611                                            OG_REST_PARAM_ID |
4612                                            OG_REST_PARAM_NAME |
4613                                            OG_REST_PARAM_REPO |
4614                                            OG_REST_PARAM_PROFILE |
4615                                            OG_REST_PARAM_TYPE |
4616                                            OG_REST_PARAM_SYNC_DIFF_ID |
4617                                            OG_REST_PARAM_SYNC_DIFF_NAME |
4618                                            OG_REST_PARAM_SYNC_PATH |
4619                                            OG_REST_PARAM_SYNC_METHOD |
4620                                            OG_REST_PARAM_SYNC_SYNC |
4621                                            OG_REST_PARAM_SYNC_DIFF |
4622                                            OG_REST_PARAM_SYNC_REMOVE |
4623                                            OG_REST_PARAM_SYNC_COMPRESS |
4624                                            OG_REST_PARAM_SYNC_CLEANUP |
4625                                            OG_REST_PARAM_SYNC_CACHE |
4626                                            OG_REST_PARAM_SYNC_CLEANUP_CACHE |
4627                                            OG_REST_PARAM_SYNC_REMOVE_DST))
4628                return -1;
4629
[d52c6d0]4630        len = snprintf(buf, sizeof(buf),
4631                       "nfn=RestaurarSoftIncremental\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\r"
4632                           "ipr=%s\rifs=%s\ridf=%s\rncf=%s\rrti=%s\rmet=%s\rmsy=%s\r"
4633                           "tpt=%s\rwhl=%s\reli=%s\rcmp=%s\rbpi=%s\rcpc=%s\rbpc=%s\r"
4634                           "nba=%s\r",
4635                       params->disk, params->partition, params->id, params->name,
4636                           params->repository, params->profile, params->sync_setup.diff_id,
4637                           params->sync_setup.diff_name, params->sync_setup.path,
4638                           params->sync_setup.method, params->sync_setup.sync, params->type,
4639                           params->sync_setup.diff, params->sync_setup.remove,
4640                       params->sync_setup.compress, params->sync_setup.cleanup,
4641                       params->sync_setup.cache, params->sync_setup.cleanup_cache,
4642                       params->sync_setup.remove_dst);
4643
4644        msg = og_msg_alloc(buf, len);
4645        if (!msg)
4646                return -1;
4647
4648        og_send_cmd((char **)params->ips_array, params->ips_array_len,
4649                    CLIENTE_OCUPADO, msg);
4650
4651        og_msg_free(msg);
4652
4653        return 0;
4654}
4655
[7dc8fdb]4656static int og_client_method_not_found(struct og_client *cli)
4657{
4658        /* To meet RFC 7231, this function MUST generate an Allow header field
4659         * containing the correct methods. For example: "Allow: POST\r\n"
4660         */
4661        char buf[] = "HTTP/1.1 405 Method Not Allowed\r\n"
4662                     "Content-Length: 0\r\n\r\n";
4663
4664        send(og_client_socket(cli), buf, strlen(buf), 0);
4665
4666        return -1;
4667}
4668
[c1c89e1]4669static int og_client_bad_request(struct og_client *cli)
4670{
4671        char buf[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n";
4672
4673        send(og_client_socket(cli), buf, strlen(buf), 0);
4674
4675        return -1;
4676}
4677
[95e6520]4678static int og_client_not_found(struct og_client *cli)
4679{
4680        char buf[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
4681
4682        send(og_client_socket(cli), buf, strlen(buf), 0);
4683
4684        return -1;
4685}
4686
[fd30540]4687static int og_client_not_authorized(struct og_client *cli)
4688{
[66001f0]4689        char buf[] = "HTTP/1.1 401 Unauthorized\r\n"
4690                     "WWW-Authenticate: Basic\r\n"
4691                     "Content-Length: 0\r\n\r\n";
[fd30540]4692
4693        send(og_client_socket(cli), buf, strlen(buf), 0);
4694
4695        return -1;
4696}
4697
[15685e6]4698static int og_server_internal_error(struct og_client *cli)
4699{
4700        char buf[] = "HTTP/1.1 500 Internal Server Error\r\n"
4701                     "Content-Length: 0\r\n\r\n";
4702
4703        send(og_client_socket(cli), buf, strlen(buf), 0);
4704
4705        return -1;
4706}
4707
[e80c85f]4708#define OG_MSG_RESPONSE_MAXLEN  65536
4709
[7b6fcdb]4710static int og_client_ok(struct og_client *cli, char *buf_reply)
[95e6520]4711{
[e80c85f]4712        char buf[OG_MSG_RESPONSE_MAXLEN] = {};
[fbc30b2]4713        int err = 0, len;
[7b6fcdb]4714
[fbc30b2]4715        len = snprintf(buf, sizeof(buf),
4716                       "HTTP/1.1 200 OK\r\nContent-Length: %ld\r\n\r\n%s",
4717                       strlen(buf_reply), buf_reply);
[15685e6]4718        if (len >= (int)sizeof(buf))
4719                err = og_server_internal_error(cli);
[95e6520]4720
4721        send(og_client_socket(cli), buf, strlen(buf), 0);
4722
[fbc30b2]4723        return err;
[95e6520]4724}
4725
4726enum og_rest_method {
4727        OG_METHOD_GET   = 0,
4728        OG_METHOD_POST,
4729};
4730
4731static int og_client_state_process_payload_rest(struct og_client *cli)
4732{
[e80c85f]4733        char buf_reply[OG_MSG_RESPONSE_MAXLEN] = {};
[95e6520]4734        struct og_msg_params params = {};
4735        enum og_rest_method method;
[eb6aa82]4736        const char *cmd, *body;
[95e6520]4737        json_error_t json_err;
4738        json_t *root = NULL;
4739        int err = 0;
4740
[84a2563]4741        syslog(LOG_DEBUG, "%s:%hu %.32s ...\n",
4742               inet_ntoa(cli->addr.sin_addr),
4743               ntohs(cli->addr.sin_port), cli->buf);
4744
[95e6520]4745        if (!strncmp(cli->buf, "GET", strlen("GET"))) {
4746                method = OG_METHOD_GET;
4747                cmd = cli->buf + strlen("GET") + 2;
4748        } else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
4749                method = OG_METHOD_POST;
4750                cmd = cli->buf + strlen("POST") + 2;
4751        } else
[7dc8fdb]4752                return og_client_method_not_found(cli);
[95e6520]4753
4754        body = strstr(cli->buf, "\r\n\r\n") + 4;
4755
[fd30540]4756        if (strcmp(cli->auth_token, auth_token)) {
4757                syslog(LOG_ERR, "wrong Authentication key\n");
4758                return og_client_not_authorized(cli);
4759        }
4760
[eb6aa82]4761        if (cli->content_length) {
[95e6520]4762                root = json_loads(body, 0, &json_err);
4763                if (!root) {
4764                        syslog(LOG_ERR, "malformed json line %d: %s\n",
4765                               json_err.line, json_err.text);
4766                        return og_client_not_found(cli);
4767                }
4768        }
4769
4770        if (!strncmp(cmd, "clients", strlen("clients"))) {
[7b6fcdb]4771                if (method != OG_METHOD_POST &&
4772                    method != OG_METHOD_GET)
[7dc8fdb]4773                        return og_client_method_not_found(cli);
[7b6fcdb]4774
4775                if (method == OG_METHOD_POST && !root) {
[95e6520]4776                        syslog(LOG_ERR, "command clients with no payload\n");
[c1c89e1]4777                        return og_client_bad_request(cli);
[95e6520]4778                }
[7b6fcdb]4779                switch (method) {
4780                case OG_METHOD_POST:
4781                        err = og_cmd_post_clients(root, &params);
4782                        break;
4783                case OG_METHOD_GET:
4784                        err = og_cmd_get_clients(root, &params, buf_reply);
4785                        break;
4786                }
[5797e0b]4787        } else if (!strncmp(cmd, "wol", strlen("wol"))) {
4788                if (method != OG_METHOD_POST)
[7dc8fdb]4789                        return og_client_method_not_found(cli);
[5797e0b]4790
4791                if (!root) {
4792                        syslog(LOG_ERR, "command wol with no payload\n");
[c1c89e1]4793                        return og_client_bad_request(cli);
[5797e0b]4794                }
4795                err = og_cmd_wol(root, &params);
[7e4e5b5]4796        } else if (!strncmp(cmd, "shell/run", strlen("shell/run"))) {
4797                if (method != OG_METHOD_POST)
[7dc8fdb]4798                        return og_client_method_not_found(cli);
[7e4e5b5]4799
4800                if (!root) {
4801                        syslog(LOG_ERR, "command run with no payload\n");
[c1c89e1]4802                        return og_client_bad_request(cli);
[7e4e5b5]4803                }
4804                err = og_cmd_run_post(root, &params);
[c6020f2]4805        } else if (!strncmp(cmd, "shell/output", strlen("shell/output"))) {
4806                if (method != OG_METHOD_POST)
[7dc8fdb]4807                        return og_client_method_not_found(cli);
[c6020f2]4808
4809                if (!root) {
4810                        syslog(LOG_ERR, "command output with no payload\n");
[c1c89e1]4811                        return og_client_bad_request(cli);
[c6020f2]4812                }
4813
4814                err = og_cmd_run_get(root, &params, buf_reply);
[7ab5f0c]4815        } else if (!strncmp(cmd, "session", strlen("session"))) {
4816                if (method != OG_METHOD_POST)
[7dc8fdb]4817                        return og_client_method_not_found(cli);
[7ab5f0c]4818
4819                if (!root) {
4820                        syslog(LOG_ERR, "command session with no payload\n");
[c1c89e1]4821                        return og_client_bad_request(cli);
[7ab5f0c]4822                }
4823                err = og_cmd_session(root, &params);
[23fed47]4824        } else if (!strncmp(cmd, "poweroff", strlen("poweroff"))) {
4825                if (method != OG_METHOD_POST)
[7dc8fdb]4826                        return og_client_method_not_found(cli);
[23fed47]4827
4828                if (!root) {
4829                        syslog(LOG_ERR, "command poweroff with no payload\n");
[c1c89e1]4830                        return og_client_bad_request(cli);
[23fed47]4831                }
4832                err = og_cmd_poweroff(root, &params);
[5f0191d]4833        } else if (!strncmp(cmd, "reboot", strlen("reboot"))) {
4834                if (method != OG_METHOD_POST)
[7dc8fdb]4835                        return og_client_method_not_found(cli);
[5f0191d]4836
4837                if (!root) {
4838                        syslog(LOG_ERR, "command reboot with no payload\n");
[c1c89e1]4839                        return og_client_bad_request(cli);
[5f0191d]4840                }
4841                err = og_cmd_reboot(root, &params);
[1e6c889]4842        } else if (!strncmp(cmd, "stop", strlen("stop"))) {
4843                if (method != OG_METHOD_POST)
[7dc8fdb]4844                        return og_client_method_not_found(cli);
[1e6c889]4845
4846                if (!root) {
4847                        syslog(LOG_ERR, "command stop with no payload\n");
[c1c89e1]4848                        return og_client_bad_request(cli);
[1e6c889]4849                }
4850                err = og_cmd_stop(root, &params);
[17f55b4]4851        } else if (!strncmp(cmd, "refresh", strlen("refresh"))) {
4852                if (method != OG_METHOD_POST)
[7dc8fdb]4853                        return og_client_method_not_found(cli);
[17f55b4]4854
4855                if (!root) {
4856                        syslog(LOG_ERR, "command refresh with no payload\n");
[c1c89e1]4857                        return og_client_bad_request(cli);
[17f55b4]4858                }
4859                err = og_cmd_refresh(root, &params);
[6b30dbc]4860        } else if (!strncmp(cmd, "hardware", strlen("hardware"))) {
4861                if (method != OG_METHOD_POST)
[7dc8fdb]4862                        return og_client_method_not_found(cli);
[6b30dbc]4863
4864                if (!root) {
4865                        syslog(LOG_ERR, "command hardware with no payload\n");
[c1c89e1]4866                        return og_client_bad_request(cli);
[6b30dbc]4867                }
4868                err = og_cmd_hardware(root, &params);
[b4a9fdd]4869        } else if (!strncmp(cmd, "software", strlen("software"))) {
4870                if (method != OG_METHOD_POST)
[7dc8fdb]4871                        return og_client_method_not_found(cli);
[b4a9fdd]4872
4873                if (!root) {
4874                        syslog(LOG_ERR, "command software with no payload\n");
[c1c89e1]4875                        return og_client_bad_request(cli);
[b4a9fdd]4876                }
4877                err = og_cmd_software(root, &params);
[01e77f4]4878        } else if (!strncmp(cmd, "image/create/basic",
4879                            strlen("image/create/basic"))) {
4880                if (method != OG_METHOD_POST)
4881                        return og_client_method_not_found(cli);
4882
4883                if (!root) {
4884                        syslog(LOG_ERR, "command create with no payload\n");
4885                        return og_client_bad_request(cli);
4886                }
4887                err = og_cmd_create_basic_image(root, &params);
[43c7da8]4888        } else if (!strncmp(cmd, "image/create/incremental",
4889                            strlen("image/create/incremental"))) {
4890                if (method != OG_METHOD_POST)
4891                        return og_client_method_not_found(cli);
4892
4893                if (!root) {
4894                        syslog(LOG_ERR, "command create with no payload\n");
4895                        return og_client_bad_request(cli);
4896                }
4897                err = og_cmd_create_incremental_image(root, &params);
[1a8ada1]4898        } else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
4899                if (method != OG_METHOD_POST)
4900                        return og_client_method_not_found(cli);
4901
4902                if (!root) {
4903                        syslog(LOG_ERR, "command create with no payload\n");
4904                        return og_client_bad_request(cli);
4905                }
4906                err = og_cmd_create_image(root, &params);
[f61fd9a]4907        } else if (!strncmp(cmd, "image/restore/basic",
4908                                strlen("image/restore/basic"))) {
4909                if (method != OG_METHOD_POST)
4910                        return og_client_method_not_found(cli);
4911
4912                if (!root) {
4913                        syslog(LOG_ERR, "command create with no payload\n");
4914                        return og_client_bad_request(cli);
4915                }
4916                err = og_cmd_restore_basic_image(root, &params);
[d52c6d0]4917        } else if (!strncmp(cmd, "image/restore/incremental",
4918                                strlen("image/restore/incremental"))) {
4919                if (method != OG_METHOD_POST)
4920                        return og_client_method_not_found(cli);
4921
4922                if (!root) {
4923                        syslog(LOG_ERR, "command create with no payload\n");
4924                        return og_client_bad_request(cli);
4925                }
4926                err = og_cmd_restore_incremental_image(root, &params);
[1dde02e]4927        } else if (!strncmp(cmd, "image/restore", strlen("image/restore"))) {
4928                if (method != OG_METHOD_POST)
4929                        return og_client_method_not_found(cli);
4930
4931                if (!root) {
4932                        syslog(LOG_ERR, "command create with no payload\n");
4933                        return og_client_bad_request(cli);
4934                }
4935                err = og_cmd_restore_image(root, &params);
[6c91d14]4936        } else if (!strncmp(cmd, "setup", strlen("setup"))) {
[dbcc83d]4937                if (method != OG_METHOD_POST)
4938                        return og_client_method_not_found(cli);
4939
4940                if (!root) {
4941                        syslog(LOG_ERR, "command create with no payload\n");
4942                        return og_client_bad_request(cli);
4943                }
[6c91d14]4944                err = og_cmd_setup(root, &params);
[2f7e9da]4945        } else if (!strncmp(cmd, "run/schedule", strlen("run/schedule"))) {
4946                if (method != OG_METHOD_POST)
4947                        return og_client_method_not_found(cli);
4948
4949                if (!root) {
4950                        syslog(LOG_ERR, "command create with no payload\n");
4951                        return og_client_bad_request(cli);
4952                }
4953
4954                err = og_cmd_run_schedule(root, &params);
[95e6520]4955        } else {
[7c67487]4956                syslog(LOG_ERR, "unknown command: %.32s ...\n", cmd);
[95e6520]4957                err = og_client_not_found(cli);
4958        }
4959
[7b6fcdb]4960        if (root)
4961                json_decref(root);
[95e6520]4962
[a12af6a]4963        if (err < 0)
4964                return err;
4965
4966        err = og_client_ok(cli, buf_reply);
4967        if (err < 0) {
4968                syslog(LOG_ERR, "HTTP response to %s:%hu is too large\n",
4969                       inet_ntoa(cli->addr.sin_addr),
4970                       ntohs(cli->addr.sin_port));
4971        }
[95e6520]4972
4973        return err;
4974}
4975
4976static int og_client_state_recv_hdr_rest(struct og_client *cli)
4977{
[eb6aa82]4978        char *ptr;
[95e6520]4979
[eb6aa82]4980        ptr = strstr(cli->buf, "\r\n\r\n");
4981        if (!ptr)
[95e6520]4982                return 0;
4983
[eb6aa82]4984        cli->msg_len = ptr - cli->buf + 4;
4985
4986        ptr = strstr(cli->buf, "Content-Length: ");
4987        if (ptr) {
4988                sscanf(ptr, "Content-Length: %i[^\r\n]", &cli->content_length);
[36ad006]4989                if (cli->content_length < 0)
4990                        return -1;
[eb6aa82]4991                cli->msg_len += cli->content_length;
4992        }
4993
[fd30540]4994        ptr = strstr(cli->buf, "Authorization: ");
4995        if (ptr)
[64e6537]4996                sscanf(ptr, "Authorization: %63[^\r\n]", cli->auth_token);
[fd30540]4997
[95e6520]4998        return 1;
4999}
5000
[107b17a]5001static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
5002{
5003        struct og_client *cli;
5004        int ret;
[212280e]5005
5006        cli = container_of(io, struct og_client, io);
5007
[f09aca6]5008        if (events & EV_ERROR) {
5009                syslog(LOG_ERR, "unexpected error event from client %s:%hu\n",
5010                               inet_ntoa(cli->addr.sin_addr),
5011                               ntohs(cli->addr.sin_port));
5012                goto close;
5013        }
5014
[212280e]5015        ret = recv(io->fd, cli->buf + cli->buf_len,
5016                   sizeof(cli->buf) - cli->buf_len, 0);
[f09aca6]5017        if (ret <= 0) {
5018                if (ret < 0) {
5019                        syslog(LOG_ERR, "error reading from client %s:%hu (%s)\n",
5020                               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
5021                               strerror(errno));
5022                } else {
[2ed3a0c]5023                        syslog(LOG_DEBUG, "closed connection by %s:%hu\n",
[f09aca6]5024                               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
5025                }
[212280e]5026                goto close;
[f09aca6]5027        }
5028
5029        if (cli->keepalive_idx >= 0)
5030                return;
[212280e]5031
5032        ev_timer_again(loop, &cli->timer);
5033
5034        cli->buf_len += ret;
[20dcb0a]5035        if (cli->buf_len >= sizeof(cli->buf)) {
5036                syslog(LOG_ERR, "client request from %s:%hu is too long\n",
5037                       inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
5038                goto close;
5039        }
[212280e]5040
5041        switch (cli->state) {
5042        case OG_CLIENT_RECEIVING_HEADER:
[95e6520]5043                if (cli->rest)
5044                        ret = og_client_state_recv_hdr_rest(cli);
5045                else
5046                        ret = og_client_state_recv_hdr(cli);
5047
[d491dfd]5048                if (ret < 0)
[212280e]5049                        goto close;
[d491dfd]5050                if (!ret)
5051                        return;
[212280e]5052
5053                cli->state = OG_CLIENT_RECEIVING_PAYLOAD;
5054                /* Fall through. */
5055        case OG_CLIENT_RECEIVING_PAYLOAD:
5056                /* Still not enough data to process request. */
5057                if (cli->buf_len < cli->msg_len)
5058                        return;
5059
5060                cli->state = OG_CLIENT_PROCESSING_REQUEST;
5061                /* fall through. */
5062        case OG_CLIENT_PROCESSING_REQUEST:
[a12af6a]5063                if (cli->rest) {
[95e6520]5064                        ret = og_client_state_process_payload_rest(cli);
[a12af6a]5065                        if (ret < 0) {
5066                                syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
5067                                       inet_ntoa(cli->addr.sin_addr),
5068                                       ntohs(cli->addr.sin_port));
5069                        }
5070                } else {
[95e6520]5071                        ret = og_client_state_process_payload(cli);
[a12af6a]5072                }
[107b17a]5073                if (ret < 0)
[212280e]5074                        goto close;
5075
[f09aca6]5076                if (cli->keepalive_idx < 0) {
[2ed3a0c]5077                        syslog(LOG_DEBUG, "server closing connection to %s:%hu\n",
[f09aca6]5078                               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
[212280e]5079                        goto close;
[f09aca6]5080                } else {
[2ed3a0c]5081                        syslog(LOG_DEBUG, "leaving client %s:%hu in keepalive mode\n",
[f09aca6]5082                               inet_ntoa(cli->addr.sin_addr),
5083                               ntohs(cli->addr.sin_port));
5084                        og_client_keepalive(loop, cli);
5085                        og_client_reset_state(cli);
5086                }
[212280e]5087                break;
[ef6e3d2]5088        default:
5089                syslog(LOG_ERR, "unknown state, critical internal error\n");
5090                goto close;
[8e0216a]5091        }
[212280e]5092        return;
5093close:
5094        ev_timer_stop(loop, &cli->timer);
[f09aca6]5095        og_client_release(loop, cli);
[8e0216a]5096}
5097
[212280e]5098static void og_client_timer_cb(struct ev_loop *loop, ev_timer *timer, int events)
5099{
5100        struct og_client *cli;
5101
5102        cli = container_of(timer, struct og_client, timer);
[f09aca6]5103        if (cli->keepalive_idx >= 0) {
[212280e]5104                ev_timer_again(loop, &cli->timer);
5105                return;
5106        }
[f09aca6]5107        syslog(LOG_ERR, "timeout request for client %s:%hu\n",
5108               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
[ef6e3d2]5109
[f09aca6]5110        og_client_release(loop, cli);
[212280e]5111}
5112
[95e6520]5113static int socket_s, socket_rest;
5114
[212280e]5115static void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io,
5116                                int events)
5117{
5118        struct sockaddr_in client_addr;
5119        socklen_t addrlen = sizeof(client_addr);
5120        struct og_client *cli;
5121        int client_sd;
5122
5123        if (events & EV_ERROR)
5124                return;
5125
5126        client_sd = accept(io->fd, (struct sockaddr *)&client_addr, &addrlen);
5127        if (client_sd < 0) {
[b56cbeb]5128                syslog(LOG_ERR, "cannot accept client connection\n");
[212280e]5129                return;
5130        }
5131
5132        cli = (struct og_client *)calloc(1, sizeof(struct og_client));
5133        if (!cli) {
5134                close(client_sd);
5135                return;
5136        }
[ef6e3d2]5137        memcpy(&cli->addr, &client_addr, sizeof(client_addr));
[f09aca6]5138        cli->keepalive_idx = -1;
[ef6e3d2]5139
[95e6520]5140        if (io->fd == socket_rest)
5141                cli->rest = true;
5142
[2ed3a0c]5143        syslog(LOG_DEBUG, "connection from client %s:%hu\n",
[f09aca6]5144               inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
[212280e]5145
5146        ev_io_init(&cli->io, og_client_read_cb, client_sd, EV_READ);
5147        ev_io_start(loop, &cli->io);
5148        ev_timer_init(&cli->timer, og_client_timer_cb, OG_CLIENT_TIMEOUT, 0.);
5149        ev_timer_start(loop, &cli->timer);
5150}
5151
[e3e4e6f]5152static int og_socket_server_init(const char *port)
5153{
5154        struct sockaddr_in local;
5155        int sd, on = 1;
5156
5157        sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
5158        if (sd < 0) {
5159                syslog(LOG_ERR, "cannot create main socket\n");
5160                return -1;
5161        }
5162        setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int));
5163
5164        local.sin_addr.s_addr = htonl(INADDR_ANY);
5165        local.sin_family = AF_INET;
5166        local.sin_port = htons(atoi(port));
5167
5168        if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
[8b1bedd]5169                close(sd);
[e3e4e6f]5170                syslog(LOG_ERR, "cannot bind socket\n");
5171                return -1;
5172        }
5173
5174        listen(sd, 250);
5175
5176        return sd;
5177}
5178
[212280e]5179int main(int argc, char *argv[])
5180{
[95e6520]5181        struct ev_io ev_io_server, ev_io_server_rest;
[212280e]5182        struct ev_loop *loop = ev_default_loop(0);
5183        int i;
[b9eb98b]5184
[9fc0037]5185        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
5186                exit(EXIT_FAILURE);
5187
[57c8c50]5188        openlog("ogAdmServer", LOG_PID, LOG_DAEMON);
[ef6e3d2]5189
[b9eb98b]5190        /*--------------------------------------------------------------------------------------------------------
5191         Validación de parámetros de ejecución y lectura del fichero de configuración del servicio
5192         ---------------------------------------------------------------------------------------------------------*/
5193        if (!validacionParametros(argc, argv, 1)) // Valida parámetros de ejecución
5194                exit(EXIT_FAILURE);
5195
5196        if (!tomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuracion
5197                exit(EXIT_FAILURE);
5198        }
5199
5200        /*--------------------------------------------------------------------------------------------------------
5201         // Inicializa array de información de los clientes
5202         ---------------------------------------------------------------------------------------------------------*/
5203        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
5204                tbsockets[i].ip[0] = '\0';
[f09aca6]5205                tbsockets[i].cli = NULL;
[b9eb98b]5206        }
5207        /*--------------------------------------------------------------------------------------------------------
5208         Creación y configuración del socket del servicio
5209         ---------------------------------------------------------------------------------------------------------*/
[e3e4e6f]5210        socket_s = og_socket_server_init(puerto);
5211        if (socket_s < 0)
[b9eb98b]5212                exit(EXIT_FAILURE);
[212280e]5213
5214        ev_io_init(&ev_io_server, og_server_accept_cb, socket_s, EV_READ);
5215        ev_io_start(loop, &ev_io_server);
5216
[95e6520]5217        socket_rest = og_socket_server_init("8888");
5218        if (socket_rest < 0)
5219                exit(EXIT_FAILURE);
5220
5221        ev_io_init(&ev_io_server_rest, og_server_accept_cb, socket_rest, EV_READ);
5222        ev_io_start(loop, &ev_io_server_rest);
5223
[b9eb98b]5224        infoLog(1); // Inicio de sesión
[212280e]5225
[effbcea]5226        /* old log file has been deprecated. */
5227        og_log(97, false);
5228
[ef6e3d2]5229        syslog(LOG_INFO, "Waiting for connections\n");
5230
[212280e]5231        while (1)
5232                ev_loop(loop, 0);
5233
[b9eb98b]5234        exit(EXIT_SUCCESS);
5235}
Note: See TracBrowser for help on using the repository browser.