source: ogServer-Git/sources/ogAdmServer.cpp @ a245411

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

#924 Fix that only the commands without session were checked

Irina reports that the bug fixed in 78a97c5 happens again when you run a
command with a session (queue of actions).

The bug was introduced in 78a97c5, the goal of the commit was
to change the behaviour of respuestaEstandar to always check
the result of a command, whether it has a session or not. But, instead
of this behaviour, the commit changes respuestaEstandar to only check the
commands without session.

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