source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ 5050850

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacion
Last change on this file since 5050850 was d2a9dd8, checked in by OpenGnSys Support Team <soporte-og@…>, 6 years ago

#896 Fix memory leak in wake_up_broadcast()

call freeifaddrs() after getifaddrs() to release memory.

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