source: admin/Services/ogAdmServer/sources/ogAdmServer.cpp @ 73cfa0a

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-instalacionwebconsole3
Last change on this file since 73cfa0a was c3e2eb6a, checked in by alonso <alonso@…>, 15 years ago

git-svn-id: https://opengnsys.es/svn/trunk@1024 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 152.1 KB
Line 
1// *************************************************************************
2// Aplicación: OPENGNSYS
3// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
4// Fecha Creación: Año 2003-2004
5// Fecha Última modificación: Marzo-2006
6// Nombre del fichero: ogAdmServer.cpp
7// Descripción :
8//              Este módulo de la aplicación OpenGNSys implementa las comunicaciones con el Servidor.
9// ****************************************************************************
10#include "ogAdmServer.h"
11#include "ogAdmLib.c"
12// ________________________________________________________________________________________________________
13// Función: TomaEnvio
14//
15//              Descripción:
16//                      Toma la hora actual  del sistema para identificar envios multicast
17//              Parámetros:
18//                      Ninguno
19// ________________________________________________________________________________________________________
20unsigned int TomaEnvio() {
21        time_t rawtime;
22        time(&rawtime);
23        return (rawtime);
24}
25//________________________________________________________________________________________________________
26//
27// Función: TomaConfiguracion
28//
29//              Descripción:
30//                      Esta función lee el fichero de configuración del programa hidralinuxcli  y toma los parámetros
31//              Parametros:
32//                              - pathfilecfg : Ruta al fichero de configuración
33//________________________________________________________________________________________________________
34int TomaConfiguracion(char* pathfilecfg) {
35        long lSize;
36        char * buffer, *lineas[100], *dualparametro[2];
37        char ch[2];
38        int i, numlin, resul;
39
40        if (pathfilecfg == NULL)
41                return (FALSE); // Nombre del fichero en blanco
42
43        Fconfig = fopen(pathfilecfg, "rb");
44        if (Fconfig == NULL)
45                return (FALSE);
46        fseek(Fconfig, 0, SEEK_END); // Obtiene tamaño del fichero.
47        lSize = ftell(Fconfig);
48        rewind(Fconfig);
49        buffer = (char*) malloc(lSize); // Toma memoria para el buffer de lectura.
50        if (buffer == NULL)
51                return (FALSE);
52        fread(buffer, 1, lSize, Fconfig); // Lee contenido del fichero
53        fclose(Fconfig);
54
55        //inicializar
56        IPlocal[0] = (char) NULL;
57        servidorhidra[0] = (char) NULL;
58        Puerto[0] = (char) NULL;
59
60        usuario[0] = (char) NULL;
61        pasguor[0] = (char) NULL;
62        datasource[0] = (char) NULL;
63        catalog[0] = (char) NULL;
64
65        strcpy(ch, "\n");// caracter delimitador ( salto de linea)
66        numlin = split_parametros(lineas, buffer, ch);
67        for (i = 0; i < numlin; i++) {
68                strcpy(ch, "=");// caracter delimitador
69                split_parametros(dualparametro, lineas[i], ch); // Toma primer nombre del parametros
70
71                resul = strcmp(dualparametro[0], "IPhidra");
72                if (resul == 0)
73                        strcpy(IPlocal, dualparametro[1]);
74
75                resul = strcmp(dualparametro[0], "IPhidra");
76                if (resul == 0)
77                        strcpy(servidorhidra, dualparametro[1]);
78
79                resul = strcmp(dualparametro[0], "Puerto");
80                if (resul == 0)
81                        strcpy(Puerto, dualparametro[1]);
82
83                resul = strcmp(dualparametro[0], "AulaUp");
84                if (resul == 0)
85                        strcpy(AulaUp, dualparametro[1]);
86
87                resul = strcmp(dualparametro[0], "Usuario");
88                if (resul == 0)
89                        strcpy(usuario, dualparametro[1]);
90
91                resul = strcmp(dualparametro[0], "PassWord");
92                if (resul == 0)
93                        strcpy(pasguor, dualparametro[1]);
94
95                resul = strcmp(dualparametro[0], "DataSource");
96                if (resul == 0)
97                        strcpy(datasource, dualparametro[1]);
98
99                resul = strcmp(dualparametro[0], "Catalog");
100                if (resul == 0)
101                        strcpy(catalog, dualparametro[1]);
102        }
103        if (IPlocal[0] == (char) NULL) {
104                RegistraLog("IPlocal, NO se ha definido este parámetro", false);
105                return (FALSE);
106        }
107        if (servidorhidra[0] == (char) NULL) {
108                RegistraLog("IPhidra, NO se ha definido este parámetro", false);
109                return (FALSE);
110        }
111        if (Puerto[0] == (char) NULL) {
112                RegistraLog("Puerto, NO se ha definido este parámetro", false);
113                return (FALSE);
114        }
115        puerto = atoi(Puerto);
116
117        if (AulaUp[0] == (char) NULL) {
118                RegistraLog("AulaUp, NO se ha definido este parámetro", false);
119                return (FALSE);
120        }
121        aulaup = atoi(AulaUp);
122
123        if (usuario[0] == (char) NULL) {
124                RegistraLog("Usuario, NO se ha definido este parámetro", false);
125                return (FALSE);
126        }
127        if (pasguor[0] == (char) NULL) {
128                RegistraLog("PassWord, NO se ha definido este parámetro", false);
129                return (FALSE);
130        }
131        if (datasource[0] == (char) NULL) {
132                RegistraLog("DataSource, NO se ha definido este parámetro", false);
133                return (FALSE);
134        }
135        if (catalog[0] == (char) NULL) {
136                RegistraLog("Catalog, NO se ha definido este parámetro", false);
137                return (FALSE);
138        }
139        return (TRUE);
140}
141// ________________________________________________________________________________________________________
142// Función: GestionaConexion
143//
144//              Descripción:
145//                      Esta hebra es la encargada de comunicarse con los clientes  a traves del socket enviado como parámetro.
146//              Parametros:
147//                      - s : Socket usado
148// ________________________________________________________________________________________________________
149void * GestionaConexion(void* s) {
150        SOCKET socket_c = *(SOCKET*) s;
151        TRAMA trama;
152
153        if (recibe_trama(socket_c, &trama)) {
154                if (strncmp(trama.identificador, "JMMLCAMDJ", 9) == 0) // Es una trama hidra
155                        gestiona_comando(socket_c, trama);
156        }
157        return (s);
158}
159// ________________________________________________________________________________________________________
160// Función: gestiona_comando
161//
162//              Descripción:
163//                      Analiza el comando enviado por el servidor web y lo reenvía al cliente rembo o lo ejecuta
164//              Parametros:
165//                      - s : Socket usado
166//                      - trama : La trama con los parámetros del comando
167// ________________________________________________________________________________________________________
168void gestiona_comando(SOCKET s, TRAMA trama) {
169        int i, resul, idaccion, numipes, cont, estado_cliente, contOG;
170        char *parametros, *nombrefuncion;
171        char *iph, *ids, *coletilla;
172        char pids[20], ipes[MAXLON_PARAMETROSIPH];
173
174        parametros = &trama.parametros[0];
175
176        if (trama.ejecutor == '1') { // Debe ejecutar el servidor
177                INTROaFINCAD(parametros);
178                nombrefuncion = toma_parametro("nfn", parametros);
179                resul = strcmp(nombrefuncion, "InclusionCliente");
180                if (resul == 0) {
181                        if (!InclusionCliente(s, parametros))
182                                respuesta_cortesia(s);
183                        return;
184                }
185
186                resul = strcmp(nombrefuncion, "inclusion_cliWINLNX");
187                if (resul == 0) {
188                        inclusion_cliWINLNX(s, parametros);
189                        return;
190                }
191
192                resul = strcmp(nombrefuncion, "inclusion_REPO");
193                if (resul == 0) {
194                        inclusion_REPO(s, parametros);
195                        return;
196                }
197
198                resul = strcmp(nombrefuncion, "ComandosPendientes");
199                if (resul == 0) {
200                        if (!ComandosPendientes(s, parametros))
201                                respuesta_cortesia(s);
202                        return;
203                }
204
205                resul = strcmp(nombrefuncion, "RecuperaItem");
206                if (resul == 0) {
207                        if (!RecuperaItem(s, parametros))
208                                respuesta_cortesia(s);
209                        return;
210                }
211
212                resul = strcmp(nombrefuncion, "EjecutarItem");
213                if (resul == 0) {
214                        if (!EjecutarItem(s, parametros))
215                                respuesta_cortesia(s);
216                        return;
217                }
218                resul = strcmp(nombrefuncion, "DisponibilidadComandos");
219                if (resul == 0) {
220                        DisponibilidadComandos(s, parametros);
221                        respuesta_cortesia(s);
222                        return;
223                }
224                resul = strcmp(nombrefuncion, "EcoConsola");
225                if (resul == 0) {
226                        EcoConsola(s, parametros);
227                        return;
228                }
229
230                resul = strcmp(nombrefuncion, "Sondeo");
231                if (resul == 0) {
232                        Sondeo(s, parametros);
233                        return;
234                }
235
236                resul = strcmp(nombrefuncion, "Arrancar");
237                if (resul == 0) {
238                        Arrancar(parametros);
239                        return;
240                }
241
242                resul = strcmp(nombrefuncion, "Actualizar");
243                if (resul == 0) {
244                        Actualizar(parametros);
245                        return;
246                }
247
248                resul = strcmp(nombrefuncion, "Conmutar");
249                if (resul == 0) {
250                        Conmutar(parametros);
251                        return;
252                }
253                resul = strcmp(nombrefuncion, "Purgar");
254                if (resul == 0) {
255                        PurgarTablaSockets(parametros);
256                        return;
257                }
258
259                resul = strcmp(nombrefuncion, "ConsolaRemota");
260                if (resul == 0) {
261                        ConsolaRemota(parametros);
262                        return;
263                }
264
265                resul = strcmp(nombrefuncion, "RESPUESTA_Arrancar");
266                if (resul == 0) {
267                        RESPUESTA_Arrancar(s, parametros);
268                        respuesta_cortesia(s);
269                        return;
270                }
271
272                resul = strcmp(nombrefuncion, "RESPUESTA_Apagar");
273                if (resul == 0) {
274                        RESPUESTA_Apagar(s, parametros);
275                        respuesta_cortesia(s);
276                        return;
277                }
278
279                resul = strcmp(nombrefuncion, "RESPUESTA_IniciarSesion");
280                if (resul == 0) {
281                        RESPUESTA_IniciarSesion(s, parametros);
282                        respuesta_cortesia(s);
283                        return;
284                }
285
286                resul = strcmp(nombrefuncion, "RESPUESTA_Reiniciar");
287                if (resul == 0) {
288                        RESPUESTA_Reiniciar(s, parametros);
289                        respuesta_cortesia(s);
290                        return;
291                }
292
293                resul = strcmp(nombrefuncion, "RESPUESTA_IniciarSesion");
294                if (resul == 0) {
295                        RESPUESTA_Reiniciar(s, parametros);
296                        respuesta_cortesia(s);
297                        return;
298                }
299                resul = strcmp(nombrefuncion, "RESPUESTA_ExecShell");
300                if (resul == 0) {
301                        RESPUESTA_ExecShell(s, parametros);
302                        respuesta_cortesia(s);
303                        return;
304                }
305                resul = strcmp(nombrefuncion, "RESPUESTA_CrearPerfilSoftware");
306                if (resul == 0) {
307                        RESPUESTA_CrearPerfilSoftware(s, parametros);
308                        respuesta_cortesia(s);
309                        return;
310                }
311
312                resul = strcmp(nombrefuncion, "RESPUESTA_CrearSoftwareIncremental");
313                if (resul == 0) {
314                        RESPUESTA_CrearSoftwareIncremental(s, parametros);
315                        respuesta_cortesia(s);
316                        return;
317                }
318                resul = strcmp(nombrefuncion, "RESPUESTA_RestaurarImagen");
319                if (resul == 0) {
320                        RESPUESTA_RestaurarImagen(s, parametros);
321                        respuesta_cortesia(s);
322                        return;
323                }
324                resul = strcmp(nombrefuncion, "RESPUESTA_ParticionaryFormatear");
325                if (resul == 0) {
326                        RESPUESTA_ParticionaryFormatear(s, parametros);
327                        respuesta_cortesia(s);
328                        return;
329                }
330                resul = strcmp(nombrefuncion, "RESPUESTA_Configurar");
331                if (resul == 0) {
332                        RESPUESTA_Configurar(s, parametros);
333                        respuesta_cortesia(s);
334                        return;
335                }
336                resul = strcmp(nombrefuncion, "RESPUESTA_TomaConfiguracion");
337                if (resul == 0) {
338                        RESPUESTA_TomaConfiguracion(s, parametros);
339                        respuesta_cortesia(s);
340                        return;
341                }
342                resul = strcmp(nombrefuncion, "RESPUESTA_TomaHardware");
343                if (resul == 0) {
344                        RESPUESTA_TomaHardware(s, parametros);
345                        respuesta_cortesia(s);
346                        return;
347                }
348                resul = strcmp(nombrefuncion, "RESPUESTA_TomaSoftware");
349                if (resul == 0) {
350                        RESPUESTA_TomaSoftware(s, parametros);
351                        respuesta_cortesia(s);
352                        return;
353                }
354        } else { // Debe ejecutar el cliente rembo
355                coletilla = corte_iph(parametros); // toma el puntero al comienzo del parametros iph
356                INTROaFINCAD(coletilla);
357                iph = toma_parametro("iph", coletilla); // Toma ipes
358                ids = toma_parametro("ids", coletilla); // Toma identificador de la acción
359                coletilla[0] = '\0';// Corta la trama en la ip
360                strcpy(ipes, iph); // Copia la cadena de ipes
361                if (ids != NULL) {
362                        idaccion = atoi(ids);
363                        sprintf(pids, "ids=%d\r", idaccion);
364                        strcat(parametros, pids); // Le añade el identificador de la acción
365                }
366                numipes = cuenta_ipes(ipes); // Número de ipes a los que enviar las tramas
367                cont = 0;
368                contOG = 0; //Contador para saber al numero de clientes opengnsys a los que se envía el comando
369                DesmarcaServidoresRembo();
370                for (i = 0; i < MAXIMOS_SOCKETS; i++) {
371                        if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
372                                if (IgualIP(ipes, tbsockets[i].ip)) { // Si existe la IP en la cadena
373                                        estado_cliente = strcmp(tbsockets[i].estado, CLIENTE_REMBO);
374                                        if (estado_cliente == 0) { // Cliente Rembo ...
375                                                strcpy(tbsockets[i].estado, CLIENTE_OCUPADO);
376                                                contOG++;
377                                                MarcaServidoresRembo(tbsockets[i].ipsrvrmb,
378                                                                tbsockets[i].ip);
379                                        } else {
380                                                estado_cliente = strcmp(tbsockets[i].estado,
381                                                                CLIENTE_OCUPADO);
382                                                if (estado_cliente != 0) { // Cliente Windows(Windows98,Windows2000,windows XP...) y Linux
383                                                        strcpy(tbsockets[i].estado, CLIENTE_OCUPADO);
384                                                        manda_comando(tbsockets[i].sock, parametros);
385                                                }
386                                        }
387                                        cont++; // Contador de envíos de tramas a  ordenadores
388                                        if (cont == numipes)
389                                                break;
390                                }
391                        }
392                }
393                EnviaServidoresRembo(parametros, contOG);
394        }
395}
396// ________________________________________________________________________________________________________
397// Función: manda_comando
398//
399//              Descripción:
400//                      Esta función envía un comando por la red (TCP) desde el servidor hidra al servidor rembo que controla al cliente que lo ejecuta
401//              Parametros:
402//                      - sock : El socket del cliente
403//                      - parametros: El contenido del comando
404// ________________________________________________________________________________________________________
405int manda_comando(SOCKET sock, char* parametros) {
406        TRAMA trama;
407        int resul;
408
409        trama.arroba = '@';
410        strncpy(trama.identificador, "JMMLCAMDJ", 9);
411        trama.ejecutor = '0';
412        strcpy(trama.parametros, parametros);
413        resul = manda_trama(sock, &trama);
414        return (resul);
415}
416// ________________________________________________________________________________________________________
417// Función: manda_trama
418//
419//              Descripción:
420//                      Esta función envía una trama por la red (TCP)
421//              Parametros:
422//                      - sock : El socket del host al que se dirige la trama
423//                      - trama: El contenido de la trama
424// ________________________________________________________________________________________________________
425int manda_trama(SOCKET sock, TRAMA* trama) {
426        int nLeft, idx, ret;
427        Encriptar((char*) trama);
428        nLeft = strlen((char*) trama);
429        idx = 0;
430        while (nLeft > 0) {
431                ret = send(sock, (char*) &trama[idx], nLeft, 0);
432
433                if (ret == 0) {
434                        break;
435                } else if (ret == SOCKET_ERROR) {
436                        RegistraLog("***send() fallo en hebra cliente", true);
437                        return (FALSE);
438                }
439                nLeft -= ret;
440                idx += ret;
441        }
442        return (TRUE);
443}
444// ________________________________________________________________________________________________________
445// Función: recibe_trama
446//
447//              Descripción:
448//                      Esta función recibe una trama por la red (TCP)
449//              Parametros:
450//                      - sock : El socket del cliente
451//                      - trama: El buffer para recibir la trama
452// ________________________________________________________________________________________________________
453int recibe_trama(SOCKET sock, TRAMA* trama) {
454        int ret;
455
456        while (1) { // Bucle para recibir datos del cliente
457                ret = recv(sock, (char*) trama, LONGITUD_TRAMA, 0);
458                if (ret == 0) // Conexión cerrada por parte del cliente (Graceful close)
459                        break;
460                else {
461                        if (ret == SOCKET_ERROR) {
462                                RegistraLog("***recv() fallo en recepcion trama", true);
463                                return (FALSE);
464                        } else
465                                // Datos recibidos
466                                break;
467                }
468        }
469        Desencriptar((char*) trama);
470        trama->parametros[ret - 11] = (char) NULL; // Coloca caracter fin de cadena en trama
471        return (TRUE);
472}
473// ________________________________________________________________________________________________________
474// Función: hay_hueco
475//
476//              Descripción:
477//                      Esta función devuelve true o false dependiendo de que haya hueco en la tabla de sockets para un nuevo cliente.
478//                      Parametros:
479//                              - idx:   Primer indice libre que se podrá utilizar
480// ________________________________________________________________________________________________________
481int hay_hueco(int *idx) {
482        int i;
483
484        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
485                if (strncmp(tbsockets[i].ip, "\0", 1) == 0) { // Hay un hueco
486                        *idx = i;
487                        return (TRUE);
488                }
489        }
490        return (FALSE);
491}
492// ________________________________________________________________________________________________________
493// Función: cliente_existente
494//
495//              Descripción:
496//                      Esta función devuelve true o false dependiendo de si el cliente está registrado en  la tabla de sockets
497//              Parámetros:
498//                              - ip : La ip del cliente a buscar
499//                              - idx:   Indice que ocupará el cliente, en el caso de estar ya registrado
500// ________________________________________________________________________________________________________
501BOOLEAN cliente_existente(char *ip, int* idx) {
502        int i;
503        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
504                if (strcmp(ip, tbsockets[i].ip) == 0) { // Si existe la IP ...
505                        *idx = i;
506                        return (TRUE);
507                }
508        }
509        return (FALSE);
510}
511// ________________________________________________________________________________________________________
512// Función: hay_huecoservidorrembo
513//
514//              Descripción:
515//                      Esta función devuelve true o false dependiendo de que haya hueco en la tabla de sockets para un nuevo servidor rembo.
516//              Parámetros:
517//                      - idx:   Primer índice libre que se podrá utilizar
518// ________________________________________________________________________________________________________
519int hay_huecoservidorrembo(int *idx) {
520        int i;
521        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
522                if (strncmp(tbsocketsSRVRMB[i].ip, "\0", 1) == 0) { // Hay un hueco
523                        *idx = i;
524                        return (TRUE);
525                }
526        }
527        return (FALSE);
528}
529// ________________________________________________________________________________________________________
530// Función: servidorrembo_existente
531//
532//              Descripción:
533//                      Esta función devuelve true o false dependiendo de si el servidor está registrado en  la tabla de sockets
534//              Parametros:
535//                              - ip : La ip del cliente a buscar
536//                              - idx   Indice que ocupará el servidor, de existir
537// ________________________________________________________________________________________________________
538BOOLEAN servidorrembo_existente(char *ip, int* idx) {
539        int i;
540        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
541                if (strcmp(ip, tbsocketsSRVRMB[i].ip) == 0) { // Si existe la IP ...
542                        *idx = i;
543                        return (TRUE);
544                }
545        }
546        return (FALSE);
547}
548
549// ________________________________________________________________________________________________________
550// Función: corte_iph
551//
552//       Descripción:
553//                      Esta función devuelve el valor del parametro iph incluido en la trama que debe ser el último parámetro de la trama.
554//        Parámetros:
555//                      - parametros: Parámetros de la trama
556// ________________________________________________________________________________________________________
557char* corte_iph(char *parametros) {
558        int i = 0;
559        char nombre_parametro[5];
560
561        strcpy(nombre_parametro, "iph=");
562        for (i = 0; i < LONGITUD_PARAMETROS - 4; i++) {
563                if (parametros[i] == nombre_parametro[0]) {
564                        if (parametros[i + 1] == nombre_parametro[1]) {
565                                if (parametros[i + 2] == nombre_parametro[2]) {
566                                        if (parametros[i + 3] == '=') {
567                                                return (&parametros[i]); //Devuelve la posicion de comienzo de la iph
568                                        }
569                                }
570                        }
571                }
572        }
573        return (NULL);
574}
575
576// ________________________________________________________________________________________________________
577// Función: escaparComillas
578//
579//       Descripción:
580//              Escapa las comillas simples de una cadena
581//       Parámetros:
582//              - cadena: Cadena de caracteres
583//       Devuelve:
584//              La cadena con las comillas escapadas "\'"
585// ________________________________________________________________________________________________________
586char* escaparComillas(char *cadena) {
587
588        int lon, i, con = 0;
589        char *cadenaescapada;
590
591        lon = strlen(cadena);
592        for (i = 0; i < lon; i++) { // Cuenta las comillas
593                if (cadena[i] == COMILLAS_SIMPES)
594                        con++;
595        }
596        if (con > 0) { // Existen comillas
597                cadenaescapada = (char*) malloc(lon + con); // Toma memoria para la cadena escapada.
598                if (cadenaescapada == NULL)
599                        return (NULL);
600                int ptr = 0;
601                for (i = 0; i < lon; i++) {
602                        if (cadena[i] == COMILLAS_SIMPES)
603                                cadenaescapada[ptr++] = BARRA_INVERTIDA;
604                        cadenaescapada[ptr++] = cadena[i];
605                }
606        } else
607                cadenaescapada = cadena;
608
609        return (cadenaescapada);
610}
611// ________________________________________________________________________________________________________
612// Función: respuesta_cortesia
613//
614//       Descripción:
615//              Envía respuesta de cortesía al cliente rembo
616//        Parámetros:
617//                      - s: Socket usado por el cliente para comunicarse con el servidor HIDRA
618// ________________________________________________________________________________________________________
619int respuesta_cortesia(SOCKET s) {
620        char nwparametros[100];
621
622        nwparametros[0] = '\0';
623        strcat(nwparametros, "nfn=Cortesia");
624        strcat(nwparametros, "\r");
625        return (manda_comando(s, nwparametros));
626}
627// ________________________________________________________________________________________________________
628// Función: NoComandosPendientes
629//
630//              Descripción:
631//                      Envía respuesta de cortesía al cliente rembo
632//        Parámetros:
633//                      - s: Socket usado por el cliente para comunicarse con el servidor HIDRA
634// ________________________________________________________________________________________________________
635int NoComandosPendientes(SOCKET s) {
636        char nwparametros[100];
637
638        nwparametros[0] = '\0';
639        strcat(nwparametros, "nfn=NoComandosPtes");
640        strcat(nwparametros, "\r");
641        return (manda_comando(s, nwparametros));
642}
643// ________________________________________________________________________________________________________
644// Función: InclusionCliente
645//
646//              Descripción:
647//                      Esta función incorpora el socket de un nuevo cliente a la tabla de sockets y le devuelve alguna de sus propiedades: nombre,
648//                      identificador, perfil hardware , mens...
649//              Parámetros:
650//                      - s: Socket del cliente
651//                      - parametros: Parámetros de la trama recibida
652// ________________________________________________________________________________________________________
653int InclusionCliente(SOCKET s, char *parametros) {
654        char ErrStr[200], sqlstr[1000];
655        Database db;
656        Table tbl;
657
658        char *iph, *cfg, *mac, *nau, *nor, *ipr, *ipd;
659        int i, lon, glon, idx, resul, puertorepo;
660        char nwparametros[LONGITUD_PARAMETROS];
661        char ipservidordhcp[16], ipservidorrembo[16], nombreordenador[100],
662                        ipmulticast[16];
663        int idordenador, idaula, idconfiguracion, idparticion, idperfilhard,
664                        idmenu, cache, pormulticast, modmulticast, velmulticast;
665
666        // Toma parámetros
667        iph = toma_parametro("iph", parametros); // Toma ip
668        mac = toma_parametro("mac", parametros); // Toma mac
669        cfg = toma_parametro("cfg", parametros); // Toma configuracion
670        nau = toma_parametro("nau", parametros); // Toma nombre del grupo em el           fichero config de rembo
671        nor = toma_parametro("nor", parametros); // Toma nombre del ordenador en el  fichero config de rembo
672        ipd = toma_parametro("ipd", parametros); // Toma ip del servidor dhcpd
673        ipr = toma_parametro("ipr", parametros); // Toma ip del servidor rembo
674
675        // Toma las propiedades del ordenador
676        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
677                RegistraLog("Error de conexión con la base de datos", false);
678                db.GetErrorErrStr(ErrStr);
679                return (false);
680        }
681        // Recupera los datos del ordenador
682        sprintf(
683                        sqlstr,
684                        "SELECT ordenadores.idordenador,ordenadores.idaula,ordenadores.nombreordenador, ordenadores.idperfilhard,"
685                                " ordenadores.idconfiguracion,ordenadores.idparticion,"
686                                " servidoresrembo.ip AS ipservidorrembo,servidoresrembo.puertorepo,"
687                                " ordenadores.idmenu,ordenadores.cache,ordenadores.ipmul,ordenadores.pormul,ordenadores.modomul,ordenadores.velmul"
688                                " FROM ordenadores"
689                                " INNER JOIN  servidoresrembo ON ordenadores.idservidorrembo = servidoresrembo.idservidorrembo"
690                                " WHERE ordenadores.ip = '%s'", iph);
691
692        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
693                RegistraLog("Error al ejecutar la consulta", false);
694                db.GetErrorErrStr(ErrStr);
695                return (false);
696        }
697        if (tbl.ISEOF()) { // Si No existe registro
698                RegistraLog("Cliente No encontrado, se rechaza la petición", false);
699                if (aulaup == AUTOINCORPORACION_OFF) // No está activada la incorporación automática
700                        return (false);
701                if (!cuestion_nuevoordenador(db, tbl, &idordenador, nau, nor, iph, mac,
702                                cfg, ipd, ipr)) // Ha habido algún error en la incorporación automónica
703                        return (false);
704                // Valores por defecto del nuevo ordenador
705                strcpy(nombreordenador, nor);
706                idperfilhard = 0;
707                strcpy(ipservidordhcp, ipd);
708                strcpy(ipservidorrembo, ipr);
709                idmenu = 0;
710        } else {
711                //      sprintf(msglog,"Petición de Inclusión del CLiente:%s",iph);
712                //      RegistraLog(msglog,false);
713
714                if (!tbl.Get("idordenador", idordenador)) { // Toma dato
715                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
716                        return (false);
717                }
718                if (!tbl.Get("nombreordenador", nombreordenador)) { // Toma dato
719                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
720                        return (false);
721                }
722                if (!tbl.Get("idaula", idaula)) { // Toma dato
723                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
724                        return (false);
725                }
726
727                if (!tbl.Get("idconfiguracion", idconfiguracion)) { // Toma dato
728                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
729                        return (false);
730                }
731                if (!tbl.Get("idparticion", idparticion)) { // Toma dato
732                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
733                        return (false);
734                }
735                if (!tbl.Get("idperfilhard", idperfilhard)) { // Toma dato
736                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
737                        return (false);
738                }
739                /*
740                 if(!tbl.Get("ipservidordhcp",ipservidordhcp)){ // Toma dato
741                 tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
742                 return(false);
743                 }
744
745                 lon=strlen(ipservidordhcp);
746                 for (i=0;i<lon;i++){
747                 if(ipservidordhcp[i]==' ') {
748                 ipservidordhcp[i]='\0';
749                 break;
750                 }
751                 }
752                 */
753                if (!tbl.Get("ipservidorrembo", ipservidorrembo)) { // Toma dato
754                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
755                        return (false);
756                }
757                lon = strlen(ipservidorrembo);
758                for (i = 0; i < lon; i++) {
759                        if (ipservidorrembo[i] == ' ') {
760                                ipservidorrembo[i] = '\0';
761                                break;
762                        }
763                }
764                if (!tbl.Get("puertorepo", puertorepo)) { // Toma dato
765                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
766                        return (false);
767                }
768
769                if (!tbl.Get("idmenu", idmenu)) { // Toma dato
770                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
771                        return (false);
772                }
773                if (!tbl.Get("cache", cache)) { // Toma dato
774                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
775                        return (false);
776                }
777                if (!tbl.Get("ipmul", ipmulticast)) { // Toma dato
778                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
779                        return (false);
780                }
781                if (!tbl.Get("pormul", pormulticast)) { // Toma dato
782                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
783                        return (false);
784                }
785                if (!tbl.Get("modomul", modmulticast)) { // Toma dato
786                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
787                        return (false);
788                }
789                if (!tbl.Get("velmul", velmulticast)) { // Toma dato
790                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
791                        return (false);
792                }
793                resul = actualiza_configuracion(db, tbl, cfg, idconfiguracion,
794                                idparticion, iph); // Actualiza la configuración del ordenador
795                if (!resul) {
796                        pthread_mutex_unlock(&guardia);
797                        return (false);
798                }
799        }
800        // Incluyendo al cliente en la tabla de sockets
801        if (cliente_existente(iph, &i)) { // Si ya existe la IP ...
802                idx = i;
803                //close(tbsockets[idx].sock);
804        } else {
805                if (hay_hueco(&i)) { // Busca hueco para el nuevo cliente
806                        idx = i;
807                        strcpy(tbsockets[idx].ip, iph);// Copia IP
808                } else
809                        return (false); // No hay huecos
810        }
811        strcpy(tbsockets[idx].estado, CLIENTE_INICIANDO); // Actualiza el estado del cliente
812        tbsockets[idx].sock = s; // Guarda el socket
813        //strcpy(tbsockets[idx].ipsrvdhcp,ipservidordhcp);// Guarda IP servidor dhcp
814        strcpy(tbsockets[idx].ipsrvrmb, ipservidorrembo);// Guarda IP servidor rembo
815
816        inclusion_srvRMB(ipservidorrembo, puertorepo); // Actualiza tabla de servidores rembo
817
818        // Prepara la trama
819        lon = sprintf(nwparametros, "nfn=RESPUESTA_InclusionCliente\r");
820        lon += sprintf(nwparametros + lon, "ido=%d\r", idordenador);
821        lon += sprintf(nwparametros + lon, "npc=%s\r", nombreordenador);
822        lon += sprintf(nwparametros + lon, "ida=%d\r", idaula);
823        lon += sprintf(nwparametros + lon, "hrd=%s\r", servidorhidra);
824        lon += sprintf(nwparametros + lon, "prt=%d\r", puerto);
825        lon += sprintf(nwparametros + lon, "ifh=%d\r", idperfilhard);
826        lon += sprintf(nwparametros + lon, "che=%d\r", cache);
827        lon += sprintf(nwparametros + lon, "ipr=%s\r", ipservidorrembo);
828        lon += sprintf(nwparametros + lon, "rep=%d\r", puertorepo);
829        lon += sprintf(nwparametros + lon, "ipm=%s\r", ipmulticast);
830        lon += sprintf(nwparametros + lon, "pom=%d\r", pormulticast);
831        lon += sprintf(nwparametros + lon, "mom=%d\r", modmulticast);
832        lon += sprintf(nwparametros + lon, "vlm=%d\r", velmulticast);
833
834        glon = lon;
835        if (!Toma_menu(db, tbl, nwparametros, idmenu, lon))
836                nwparametros[glon] = (char) NULL;
837        db.Close();
838        return (manda_comando(s, nwparametros));
839}
840// ________________________________________________________________________________________________________
841// Función: Toma menu
842//
843//              Descripción:
844//                      Esta función toma los parametros del menu inicial del cliente rembo y se los envía en el proceso de inclusión
845//              Parámetros:
846//                      - db: Base de datos
847//                      - tbl: Objeto tabla
848//                      - nwparametros: Cadena con los parámetros a enviar al cliente
849//                      - idmenu: Identificador del menú
850//                      - lon : Longitud inicial de la cadena de parámetros
851// ________________________________________________________________________________________________________
852int Toma_menu(Database db, Table tbl, char* nwparametros, int idmenu, int lon) {
853        Table littbl;
854
855        char sqlstr[1000], ErrStr[200], titulo[250], descripitem[250], urlimg[250];
856        int idaccionmenu, idtipoaccion, coorx, coory, idurlimg;
857        int modalidad, resolucion, tipoaccion, tipoitem;
858        char htmlmenupub[250], htmlmenupri[250];
859
860        sprintf(
861                        sqlstr,
862                        "SELECT menus.resolucion,menus.titulo,menus.coorx,menus.coory,menus.modalidad,menus.scoorx,menus.scoory,menus.smodalidad,menus.htmlmenupub,menus.htmlmenupri,acciones_menus.tipoaccion,acciones_menus.idaccionmenu,acciones_menus.idtipoaccion,acciones_menus.tipoitem,acciones_menus.descripitem,acciones_menus.idurlimg FROM acciones_menus INNER JOIN menus ON acciones_menus.idmenu = menus.idmenu WHERE menus.idmenu=%d order by acciones_menus.orden",
863                        idmenu);
864
865        if (!db.Execute(sqlstr, tbl)) { // Error al leer
866                db.GetErrorErrStr(ErrStr);
867                return (false);
868        }
869        if (tbl.ISEOF())
870                return (true);
871
872        if (!tbl.Get("titulo", titulo)) { // Toma dato
873                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
874                return (false);
875        }
876        if (!tbl.Get("coorx", coorx)) { // Toma dato
877                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
878                return (false);
879        }
880        if (!tbl.Get("coory", coory)) { // Toma dato
881                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
882                return (false);
883        }
884        if (!tbl.Get("modalidad", modalidad)) { // Toma dato
885                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
886                return (false);
887        }
888        lon += sprintf(nwparametros + lon, "cmn=%s&%d&%d&%d&", titulo, coorx,
889                        coory, modalidad); // Cabecera de menu
890
891        if (!tbl.Get("scoorx", coorx)) { // Toma dato
892                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
893                return (false);
894        }
895        if (!tbl.Get("scoory", coory)) { // Toma dato
896                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
897                return (false);
898        }
899        if (!tbl.Get("smodalidad", modalidad)) { // Toma dato
900                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
901                return (false);
902        }
903        lon += sprintf(nwparametros + lon, "%d&%d&%d", coorx, coory, modalidad); // Cabecera de menu
904
905        if (!tbl.Get("resolucion", resolucion)) { // Toma dato
906                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
907                return (false);
908        }
909        lon += sprintf(nwparametros + lon, "&%d\r", resolucion); // Resolucion de la pantalla
910
911        if (!tbl.Get("htmlmenupub", htmlmenupub)) { // Toma dato
912                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
913                return (false);
914        }
915        if (!tbl.Get("htmlmenupri", htmlmenupri)) { // Toma dato
916                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
917                return (false);
918        }
919        lon += sprintf(nwparametros + lon, "htm=%s;%s\r", htmlmenupub, htmlmenupri); // Html de menu
920
921        lon += sprintf(nwparametros + lon, "mnu=");
922        while (!tbl.ISEOF()) { // Recorre acciones del menu
923                if (!tbl.Get("tipoaccion", tipoaccion)) { // Toma dato
924                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
925                        return (false);
926                }
927                if (!tbl.Get("tipoitem", tipoitem)) { // Toma dato
928                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
929                        return (false);
930                }
931                if (!tbl.Get("idtipoaccion", idtipoaccion)) { // Toma dato
932                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
933                        return (false);
934                }
935                if (!tbl.Get("idaccionmenu", idaccionmenu)) { // Toma dato
936                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
937                        return (false);
938                }
939                if (!tbl.Get("descripitem", descripitem)) { // Toma dato
940                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
941                        return (false);
942                }
943                if (!tbl.Get("idurlimg", idurlimg)) { // Toma dato
944                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
945                        return (false);
946                }
947
948                sprintf(sqlstr, "SELECT urlicono FROM iconos WHERE idicono=%d",
949                                idurlimg);
950                if (!db.Execute(sqlstr, littbl)) { // Error al leer
951                        db.GetErrorErrStr(ErrStr);
952                        return (false);
953                }
954                if (!littbl.ISEOF()) {
955                        if (!littbl.Get("urlicono", urlimg)) { // Toma dato
956                                littbl.GetErrorErrStr(ErrStr); // error al acceder al registro
957                                return (false);
958                        }
959                } else
960                        sprintf(urlimg, "itemdefault.pcx");
961
962                lon += sprintf(nwparametros + lon, "%d&%s&%s&%d&%d\?", idaccionmenu,
963                                urlimg, descripitem, tipoitem, tipoaccion);
964                tbl.MoveNext();
965        }
966        nwparametros[lon - 1] = '\r';
967        nwparametros[lon] = (char) NULL;
968        return (true);
969}
970// ________________________________________________________________________________________________________
971// Función:RecuperaItem
972//
973//              Descripción:
974//                      Esta función busca en la base de datos, los parametros de un items de un menu
975//              Parámetros:
976//                      - s: Socket del cliente
977//                      - parametros: Parámetros de la trama recibida
978// ________________________________________________________________________________________________________
979int RecuperaItem(SOCKET s, char *parametros) {
980        char ErrStr[200], sqlstr[1000];
981        Database db;
982        Table tbl;
983        char *ida;
984        int idtipoaccion, tipoaccion;
985
986        // Toma parnetros
987        ida = toma_parametro("ida", parametros); // Toma identificador de la acción
988
989        //  Abre conexin con la base de datos
990        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
991                db.GetErrorErrStr(ErrStr);
992                return (false);
993        }
994        sprintf(
995                        sqlstr,
996                        "SELECT tipoaccion,idtipoaccion FROM acciones_menus  WHERE idaccionmenu=%s",
997                        ida);
998        if (!db.Execute(sqlstr, tbl)) { // Error al leer
999                db.GetErrorErrStr(ErrStr);
1000                return (false);
1001        }
1002        if (tbl.ISEOF())
1003                return (false);
1004
1005        if (!tbl.Get("tipoaccion", tipoaccion)) { // Toma tipo de acción
1006                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1007                return (false);
1008        }
1009        if (!tbl.Get("idtipoaccion", idtipoaccion)) { // Toma identificador del tipo de acción
1010                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1011                return (false);
1012        }
1013        switch (tipoaccion) {
1014        case EJECUCION_PROCEDIMIENTO:
1015                sprintf(
1016                                sqlstr,
1017                                "SELECT  procedimientos_comandos.parametros FROM procedimientos_comandos  WHERE procedimientos_comandos.idprocedimiento=%d",
1018                                idtipoaccion);
1019                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1020                        db.GetErrorErrStr(ErrStr);
1021                        return (false);
1022                }
1023                if (tbl.ISEOF()) // No existe procedimiento
1024                        return (false);
1025
1026                while (!tbl.ISEOF()) {
1027                        if (!tbl.Get("parametros", parametros)) { // Toma dato
1028                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1029                                return (false);
1030                        }
1031                        tbl.MoveNext();
1032                }
1033                break;
1034        case EJECUCION_TAREA:
1035                //Las tareas no se recuperan como fichero de items;
1036                break;
1037        case EJECUCION_TRABAJO:
1038                //Los t rabajos no se recuperan como fichero de items;
1039                break;
1040        }
1041        db.Close();
1042        return (manda_comando(s, parametros));
1043}
1044
1045// ________________________________________________________________________________________________________
1046// Función: actualiza_hardware
1047//
1048//              Descripción:
1049//                      Esta función actualiza la base de datos con la configuracion de sistemas operativos y particiones de un ordenador
1050//              Parámetros:
1051//                      - db: Objeto base de datos (ya operativo)
1052//                      - tbl: Objeto tabla
1053//                      - hrd: El path del archivo de inventario
1054//                      - ip: Ip del cliente
1055//                      - ido: Identificador del ordenador del cliente en la tabla
1056// ________________________________________________________________________________________________________
1057int actualiza_hardware(Database db, Table tbl, char* hrd, char* ip, char*ido) {
1058        int idtipohardware;
1059        int i, lon = 0, idcentro, widcentro;
1060        char *tbHardware[MAXHARDWARE];
1061        int tbidhardware[MAXHARDWARE];
1062        char *dualHardware[2];
1063        char ch[2]; // Carácter delimitador
1064        char sqlstr[1000], ErrStr[200], descripcion[250], nombreordenador[250];
1065
1066        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1067        // ACCESO único A TRAVES DE OBJETO MUTEX a este trozo de código
1068        pthread_mutex_lock(&guardia);
1069
1070        // Toma Centro
1071        sprintf(
1072                        sqlstr,
1073                        "SELECT aulas.idcentro,ordenadores.nombreordenador FROM aulas INNER JOIN ordenadores ON aulas.idaula=ordenadores.idaula WHERE ordenadores.idordenador=%s",
1074                        ido);
1075        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1076                db.GetErrorErrStr(ErrStr);
1077                pthread_mutex_unlock(&guardia);
1078                return (false);
1079        }
1080        if (!tbl.Get("idcentro", widcentro)) { // Toma dato
1081                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1082                pthread_mutex_unlock(&guardia);
1083                return (false);
1084        }
1085        idcentro = widcentro + 0; // Bug Mysql
1086
1087        if (!tbl.Get("nombreordenador", nombreordenador)) { // Toma dato
1088                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1089                pthread_mutex_unlock(&guardia);
1090                return (false);
1091        }
1092
1093        if (lon > MAXHARDWARE)
1094                lon = MAXHARDWARE;
1095
1096        // Lee archivo de inventario hardware
1097        FILE *Finv;
1098        char *buffer;
1099        long lSize;
1100        Finv = fopen(hrd, "rb"); // EL parámetro sft contiene el path del archivo de inventario
1101        if (Finv == NULL)
1102                return (false);
1103        fseek(Finv, 0, SEEK_END); // Obtiene tamaño del fichero.
1104        lSize = ftell(Finv);
1105        if (lSize == 0)
1106                return (false);
1107        rewind(Finv);
1108        buffer = (char*) malloc(lSize); // Toma memoria para el buffer de lectura.
1109        if (buffer == NULL)
1110                return (false);
1111        fread(buffer, 1, lSize, Finv); // Lee contenido del fichero
1112        fclose(Finv);
1113        buffer = escaparComillas(buffer);
1114
1115        // Trocea la cadena de configuración
1116        strcpy(ch, "\n");// caracter delimitador
1117        lon = split_parametros(tbHardware, buffer, ch);
1118
1119        /*
1120         for (i=0;i<lon;i++){
1121         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
1122         RegistraLog(msglog,false);
1123         }
1124         */
1125
1126        // Trocea las cadenas de parametros de partición
1127        for (i = 0; i < lon; i++) {
1128                strcpy(ch, "=");// caracter delimitador "="
1129                split_parametros(dualHardware, tbHardware[i], ch);
1130
1131                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
1132                //RegistraLog(msglog,false);
1133                //sprintf(msglog,"valor: %s",dualHardware[1]);
1134                //RegistraLog(msglog,false);
1135
1136
1137                sprintf(
1138                                sqlstr,
1139                                "SELECT idtipohardware,descripcion FROM tipohardwares WHERE nemonico='%s'",
1140                                dualHardware[0]);
1141                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1142                        db.GetErrorErrStr(ErrStr);
1143                        pthread_mutex_unlock(&guardia);
1144                        return (false);
1145                }
1146                if (tbl.ISEOF()) { //  Tipo de Hardware NO existente
1147                        sprintf(
1148                                        msglog,
1149                                        "Existe un tipo de hardware que no está registrado (nemónico:%s). Se rechaza proceso de inventario",
1150                                        dualHardware[0]);
1151                        RegistraLog(msglog, false);
1152                        pthread_mutex_unlock(&guardia);
1153                        return (false);
1154                } else { //  Tipo de Hardware Existe
1155                        if (!tbl.Get("idtipohardware", idtipohardware)) { // Toma dato
1156                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1157                                pthread_mutex_unlock(&guardia);
1158                                return (false);
1159                        }
1160                        if (!tbl.Get("descripcion", descripcion)) { // Toma dato
1161                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1162                                pthread_mutex_unlock(&guardia);
1163                                return (false);
1164                        }
1165
1166                        sprintf(
1167                                        sqlstr,
1168                                        "SELECT idhardware FROM hardwares WHERE idtipohardware=%d AND descripcion='%s'",
1169                                        idtipohardware, dualHardware[1]);
1170
1171                        // EJecuta consulta
1172                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1173                                db.GetErrorErrStr(ErrStr);
1174                                pthread_mutex_unlock(&guardia);
1175                                return (false);
1176                        }
1177
1178                        if (tbl.ISEOF()) { //  Hardware NO existente
1179                                sprintf(
1180                                                sqlstr,
1181                                                "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) VALUES(%d,'%s',%d,0)",
1182                                                idtipohardware, dualHardware[1], idcentro);
1183                                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1184                                        db.GetErrorErrStr(ErrStr);
1185                                        pthread_mutex_unlock(&guardia);
1186                                        return (false);
1187                                }
1188                                // Recupera el identificador del hardware       
1189                                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1190                                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1191                                        db.GetErrorErrStr(ErrStr);
1192                                        pthread_mutex_unlock(&guardia);
1193                                        return (false);
1194                                }
1195                                if (!tbl.ISEOF()) { // Si existe registro
1196                                        if (!tbl.Get("identificador", tbidhardware[i])) {
1197                                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1198                                                pthread_mutex_unlock(&guardia);
1199                                                return (false);
1200                                        }
1201                                }
1202                        } else {
1203                                if (!tbl.Get("idhardware", tbidhardware[i])) { // Toma dato
1204                                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1205                                        pthread_mutex_unlock(&guardia);
1206                                        return (false);
1207                                }
1208                        }
1209                } // Fin for
1210        }
1211        // Comprueba existencia de perfil hardware y actualización de éste para el ordenador
1212        if (!CuestionPerfilHardware(db, tbl, idcentro, ido, tbidhardware, i,
1213                        nombreordenador)) {
1214                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1215                pthread_mutex_unlock(&guardia);
1216                return (false);
1217        }
1218        pthread_mutex_unlock(&guardia);
1219        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////         
1220        return (true);
1221}
1222// ________________________________________________________________________________________________________
1223// Función: CuestionPerfilHardware
1224//
1225//              Parámetros:
1226//                      - db: Objeto base de datos (ya operativo)
1227//                      - tbl: Objeto tabla
1228//                      - idcentro: Identificador del centro
1229//                      - ido: Identificador del ordenador del cliente en la tabla
1230//                      - tbidhardware: Identificador hardware
1231//                      - nombreordenador: Nombre del ordenador del cliente
1232//________________________________________________________________________________________________________/
1233int CuestionPerfilHardware(Database db, Table tbl, int idcentro, char* ido,
1234                int *tbidhardware, int i, char *nombreordenador) {
1235        char sqlstr[1000], ErrStr[200];
1236        int tbidhardwareperfil[MAXHARDWARE];
1237        int j = 0;
1238        int idperfilhard;
1239        // Busca perfil hard del ordenador
1240        sprintf(
1241                        sqlstr,
1242                        "SELECT perfileshard_hardwares.idhardware FROM ordenadores INNER JOIN perfileshard ON ordenadores.idperfilhard = perfileshard.idperfilhard      INNER JOIN perfileshard_hardwares ON perfileshard_hardwares.idperfilhard = perfileshard.idperfilhard WHERE ordenadores.idordenador =%s",
1243                        ido);
1244        // EJecuta consulta
1245        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1246                db.GetErrorErrStr(ErrStr);
1247                return (false);
1248        }
1249        while (!tbl.ISEOF()) { // Recorre acciones del menu
1250                if (!tbl.Get("idhardware", tbidhardwareperfil[j++])) { // Toma dato
1251                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1252                        return (false);
1253                }
1254                tbl.MoveNext();
1255        }
1256        // Comprueba si el perfil del ordenador contiene todo el hardware enviado
1257        int k, q, sw = false;
1258        for (k = 0; k < i; k++) { // Elemento hardware
1259                for (q = 0; q < j; q++) {
1260                        if (tbidhardware[k] == tbidhardwareperfil[q]) {
1261                                sw = true;
1262                                break;
1263                        }
1264                }
1265                if (!sw)
1266                        break;
1267        }
1268        // La variable sw contiene false si se ha encontrado algún hardware que no está en el perfil hardware del ordenador
1269        if (sw)
1270                return (true); // Todo el hardware está en el perfil actual
1271
1272        // Crea perfil nuevo con todo el hardware inventariado
1273        sprintf(
1274                        sqlstr,
1275                        "INSERT perfileshard  (descripcion,idcentro,grupoid) VALUES('Perfil Hardware (%s)',%d,0)",
1276                        nombreordenador, idcentro);
1277        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1278                db.GetErrorErrStr(ErrStr);
1279                return (false);
1280        }
1281        // Recupera el identificador del hardware       
1282        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1283        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1284                db.GetErrorErrStr(ErrStr);
1285                return (false);
1286        }
1287        if (!tbl.ISEOF()) { // Si existe registro
1288                if (!tbl.Get("identificador", idperfilhard)) {
1289                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1290                        return (false);
1291                }
1292        }
1293        for (k = 0; k < i; k++) { // relaciona elementos hardwares con el nuevo perfil hardware
1294                sprintf(
1295                                sqlstr,
1296                                "INSERT perfileshard_hardwares  (idperfilhard,idhardware) VALUES(%d,%d)",
1297                                idperfilhard, tbidhardware[k]);
1298                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1299                        db.GetErrorErrStr(ErrStr);
1300                        return (false);
1301                }
1302        }
1303        sprintf(sqlstr,
1304                        "UPDATE         ordenadores SET idperfilhard=%d WHERE idordenador=%s",
1305                        idperfilhard, ido);
1306        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1307                db.GetErrorErrStr(ErrStr);
1308                return (false);
1309        }
1310        return (true);
1311}
1312// ________________________________________________________________________________________________________
1313// Función: actualiza_software
1314//
1315//              Descripción:
1316//                      Esta función actualiza la base de datos con la configuración de sistemas operativos y particiones de un ordenador
1317//              Parámetros:
1318//                      - db: Objeto base de datos (ya operativo)
1319//                      - tbl: Objeto tabla
1320//                      - sft: Software
1321//                      - par: Partición
1322//                      - tfs: Tipo de partición
1323// ________________________________________________________________________________________________________
1324int actualiza_software(Database db, Table tbl, char* sft, char* par, char* tfs,
1325                char* ip, char*ido) {
1326        int i, lon = 0, idcentro, auxint, idtiposo;
1327        char *tbSoftware[MAXSOFTWARE];
1328        int tbidsoftware[MAXSOFTWARE];
1329        char ch[2], descripso[50]; // Caracter delimitador y nombre del estandar sistema operativo
1330        char sqlstr[1000], ErrStr[200], nombreordenador[250];
1331
1332        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1333        // ACCESO único A TRAVES DE OBJETO MUTEX a este trozo de código
1334        pthread_mutex_lock(&guardia);
1335
1336        // Toma Centro
1337        sprintf(
1338                        sqlstr,
1339                        "SELECT aulas.idcentro,ordenadores.nombreordenador FROM aulas INNER JOIN ordenadores ON aulas.idaula=ordenadores.idaula WHERE ordenadores.idordenador=%s",
1340                        ido);
1341        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1342                db.GetErrorErrStr(ErrStr);
1343                pthread_mutex_unlock(&guardia);
1344                return (false);
1345        }
1346        if (!tbl.Get("idcentro", auxint)) { // Toma dato
1347                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1348                pthread_mutex_unlock(&guardia);
1349                return (false);
1350        }
1351        idcentro = auxint + 0; // Bug Mysql
1352
1353        if (!tbl.Get("nombreordenador", nombreordenador)) { // Toma dato
1354                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1355                pthread_mutex_unlock(&guardia);
1356                return (false);
1357        }
1358
1359        if (lon > MAXSOFTWARE)
1360                lon = MAXSOFTWARE;
1361        // Trocea la cadena de configuración
1362        strcpy(ch, "\n");// caracter delimitador
1363
1364
1365        // Lee archivo de inventario software
1366        FILE *Finv;
1367        char *buffer;
1368        long lSize;
1369        Finv = fopen(sft, "rb"); // EL parametro sft contiene el path del archivo de inventario
1370        if (Finv == NULL)
1371                return (false);
1372        fseek(Finv, 0, SEEK_END); // Obtiene tamaño del fichero.
1373        lSize = ftell(Finv);
1374        rewind(Finv);
1375        buffer = (char*) malloc(lSize); // Toma memoria para el buffer de lectura.
1376        if (buffer == NULL)
1377                return (false);
1378        fread(buffer, 1, lSize, Finv); // Lee contenido del fichero
1379        fclose(Finv);
1380        buffer = escaparComillas(buffer);
1381        // trocea las líneas
1382        lon = split_parametros(tbSoftware, buffer, ch);
1383
1384        // Incorpora el sistema Operativo de la partición
1385        sprintf(sqlstr,
1386                        "SELECT idtiposo,descripcion FROM tiposos WHERE tipopar ='%s'", tfs);
1387        // Ejecuta consulta
1388        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1389                db.GetErrorErrStr(ErrStr);
1390                pthread_mutex_unlock(&guardia);
1391                return (false);
1392        }
1393        if (tbl.ISEOF()) { //  Software NO existente
1394                pthread_mutex_unlock(&guardia);
1395                return (false);
1396        } else {
1397                if (!tbl.Get("idtiposo", auxint)) {
1398                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1399                        pthread_mutex_unlock(&guardia);
1400                        return (false);
1401                }
1402                idtiposo = auxint + 0; // Bug Mysql
1403                if (!tbl.Get("descripcion", descripso)) {
1404                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1405                        pthread_mutex_unlock(&guardia);
1406                        return (false);
1407                }
1408                tbSoftware[lon++] = descripso;
1409        }
1410        // Trocea las cadenas de parametros de partición
1411        for (i = 0; i < lon; i++) {
1412                sprintf(sqlstr,
1413                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
1414                                tbSoftware[i]);
1415
1416                // EJecuta consulta
1417                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1418                        db.GetErrorErrStr(ErrStr);
1419                        pthread_mutex_unlock(&guardia);
1420                        return (false);
1421                }
1422                if (tbl.ISEOF()) { //  Software NO existente
1423                        if ((lon - i) > 1) // No es el último elemento que es el S.O. el idtiposoftware es 2 (Aplicaciones)
1424                                sprintf(
1425                                                sqlstr,
1426                                                "INSERT softwares (idtiposoftware,descripcion,idcentro,grupoid) VALUES(2,'%s',%d,0)",
1427                                                tbSoftware[i], idcentro);
1428                        else
1429                                // Es el último elemento que es el S.O. el idtiposoftware es 1 (Sistemas operativos)
1430                                sprintf(
1431                                                sqlstr,
1432                                                "INSERT softwares (idtiposoftware,idtiposo,descripcion,idcentro,grupoid) VALUES(1,%d,'%s',%d,0)",
1433                                                idtiposo, tbSoftware[i], idcentro);
1434
1435                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1436                                db.GetErrorErrStr(ErrStr);
1437                                pthread_mutex_unlock(&guardia);
1438                                return (false);
1439                        }
1440                        // Recupera el identificador del software
1441                        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1442                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1443                                db.GetErrorErrStr(ErrStr);
1444                                pthread_mutex_unlock(&guardia);
1445                                return (false);
1446                        }
1447                        if (!tbl.ISEOF()) { // Si existe registro
1448                                if (!tbl.Get("identificador", tbidsoftware[i])) {
1449                                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1450                                        pthread_mutex_unlock(&guardia);
1451                                        return (false);
1452                                }
1453                        }
1454                } else {
1455                        if (!tbl.Get("idsoftware", tbidsoftware[i])) { // Toma dato
1456                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1457                                pthread_mutex_unlock(&guardia);
1458                                return (false);
1459                        }
1460                } // Fin for
1461        }
1462        // Comprueba existencia de perfil software y actualización de éste para el ordenador
1463        if (!CuestionPerfilSoftware(db, tbl, idcentro, ido, tbidsoftware, i,
1464                        nombreordenador, par)) {
1465                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1466                pthread_mutex_unlock(&guardia);
1467                return (false);
1468        }
1469        pthread_mutex_unlock(&guardia);
1470        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////         
1471        return (true);
1472}
1473// ________________________________________________________________________________________________________
1474// Función: CuestionPerfilSoftware
1475//
1476//              Parámetros:
1477//                      - db: Objeto base de datos (ya operativo)
1478//                      - tbl: Objeto tabla
1479//                      - idcentro: Identificador del centro en la tabla
1480//                      - ido: Identificador del ordenador del cliente en la tabla
1481//                      - tbidsoftware: Tipo de partición
1482//                      - i: Número de particiones
1483//                      - nombreordenador: Nombre del ordenador del cliente
1484//                      - particion: Tipo de la partición
1485//________________________________________________________________________________________________________/
1486int CuestionPerfilSoftware(Database db, Table tbl, int idcentro, char* ido,
1487                int *tbidsoftware, int i, char *nombreordenador, char *particion) {
1488        char sqlstr[1000], ErrStr[200];
1489        int tbidsoftwareperfil[MAXSOFTWARE];
1490        int j = 0;
1491        int idperfilsoft;
1492        // Busca perfil soft del ordenador
1493        sprintf(
1494                        sqlstr,
1495                        "SELECT perfilessoft_softwares.idsoftware FROM ordenador_perfilsoft INNER JOIN perfilessoft ON ordenador_perfilsoft.idperfilsoft = perfilessoft.idperfilsoft INNER JOIN perfilessoft_softwares ON perfilessoft_softwares.idperfilsoft=perfilessoft.idperfilsoft WHERE ordenador_perfilsoft.idordenador =%s",
1496                        ido);
1497        // EJecuta consulta
1498        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1499                db.GetErrorErrStr(ErrStr);
1500                return (false);
1501        }
1502        while (!tbl.ISEOF()) { // Recorre software del perfils
1503                if (!tbl.Get("idsoftware", tbidsoftwareperfil[j++])) { // Toma dato
1504                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1505                        return (false);
1506                }
1507                tbl.MoveNext();
1508        }
1509        // Comprueba si el perfil del ordenador contiene todo el software enviado
1510        int k, q, sw = false;
1511        if (i == j) { // Si son el mismo número de componenetes software ...
1512                for (k = 0; k < i; k++) { // Elemento software
1513                        for (q = 0; q < j; q++) {
1514                                if (tbidsoftware[k] == tbidsoftwareperfil[q]) {
1515                                        sw = true;
1516                                        break;
1517                                }
1518                        }
1519                        if (!sw)
1520                                break;
1521                }
1522        }
1523
1524        // La variable sw contiene false si se ha encontrado algún software que no está en el perfil software del ordenador
1525        if (sw)
1526                return (true); // Todo el software está en el perfil actual
1527
1528        // Crea perfil nuevo con todo el software inventariado
1529        sprintf(
1530                        sqlstr,
1531                        "INSERT perfilessoft  (descripcion,idcentro,grupoid) VALUES('Perfil Software (%s, Part:%s) ',%d,0)",
1532                        nombreordenador, particion, idcentro);
1533        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1534                db.GetErrorErrStr(ErrStr);
1535                return (false);
1536        }
1537        // Recupera el identificador del software       
1538        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1539        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1540                db.GetErrorErrStr(ErrStr);
1541                return (false);
1542        }
1543        if (!tbl.ISEOF()) { // Si existe registro
1544                if (!tbl.Get("identificador", idperfilsoft)) {
1545                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1546                        return (false);
1547                }
1548        }
1549        for (k = 0; k < i; k++) { // relaciona elementos softwares con el nuevo perfil software
1550                sprintf(
1551                                sqlstr,
1552                                "INSERT perfilessoft_softwares  (idperfilsoft,idsoftware) VALUES(%d,%d)",
1553                                idperfilsoft, tbidsoftware[k]);
1554                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1555                        db.GetErrorErrStr(ErrStr);
1556                        return (false);
1557                }
1558        }
1559        // Busca si existe un perfil software para ese ordenador y esa partición       
1560        sprintf(
1561                        sqlstr,
1562                        "SELECT idperfilsoft FROM ordenador_perfilsoft WHERE idordenador =%s AND particion=%s",
1563                        ido, particion);
1564        // Ejecuta consulta
1565        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1566                db.GetErrorErrStr(ErrStr);
1567                return (false);
1568        }
1569        if (!tbl.ISEOF()) { // existe un perfilsoft que se cambia al nuevo
1570                sprintf(
1571                                sqlstr,
1572                                "UPDATE         ordenador_perfilsoft SET idperfilsoft=%d WHERE idordenador=%s AND particion=%s",
1573                                idperfilsoft, ido, particion);
1574                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1575                        db.GetErrorErrStr(ErrStr);
1576                        return (false);
1577                }
1578        } else {
1579                sprintf(
1580                                sqlstr,
1581                                "INSERT INTO ordenador_perfilsoft (idordenador,particion,idperfilsoft) VALUE (%s,%s,%d)",
1582                                ido, particion, idperfilsoft);
1583                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1584                        db.GetErrorErrStr(ErrStr);
1585                        return (false);
1586                }
1587
1588        }
1589        return (true);
1590}
1591// ________________________________________________________________________________________________________
1592// Función: actualiza_configuracion
1593//
1594//              Descripción:
1595//                      Esta función actualiza la base de datos con la configuración de sistemas operativos y particiones de un ordenador
1596//              Parámetros:
1597//                      - db: Objeto base de datos (ya operativo)
1598//                      - tbl: Objeto tabla
1599//                      - cfg: cadena con una configuración
1600//                      - idcfgo: Identificador de la configuración actual del ordenador
1601//                      - idprto: Identificador de la configuración actual de las particiones del ordenador
1602//                      - ipho: Ip del ordenador
1603// ________________________________________________________________________________________________________
1604int actualiza_configuracion(Database db, Table tbl, char* cfg, int idcfgo,
1605                int idprto, char* ipho) {
1606        char sqlstr[1000], ErrStr[200];
1607        int idconfiguracion, idparticion, lon;
1608        char * part;
1609
1610        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1611        // ACCESO único A TRAVES DE OBJETO MUTEX a este trozo de código
1612        pthread_mutex_lock(&guardia);
1613        sprintf(
1614                        sqlstr,
1615                        "SELECT idconfiguracion FROM configuraciones WHERE configuracion LIKE '%s'",
1616                        cfg);
1617        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1618                db.GetErrorErrStr(ErrStr);
1619                pthread_mutex_unlock(&guardia);
1620                return (false);
1621        }
1622        if (!tbl.ISEOF()) { // Configuración ya existente
1623                if (!tbl.Get("idconfiguracion", idconfiguracion)) { // Toma dato
1624                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1625                        pthread_mutex_unlock(&guardia);
1626                        return (false);
1627                }
1628        } else { // Nueva configuración
1629                sprintf(sqlstr, "INSERT configuraciones (configuracion) VALUES('%s')",
1630                                cfg);
1631                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1632                        db.GetErrorErrStr(ErrStr);
1633                        pthread_mutex_unlock(&guardia);
1634                        return (false);
1635                }
1636                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1637                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1638                        db.GetErrorErrStr(ErrStr);
1639                        pthread_mutex_unlock(&guardia);
1640                        return (false);
1641                }
1642                if (!tbl.ISEOF()) { // Si existe registro
1643                        if (!tbl.Get("identificador", idconfiguracion)) {
1644                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1645                                pthread_mutex_unlock(&guardia);
1646                                return (false);
1647                        }
1648                }
1649        }
1650        // Genera cadena de particiones
1651        lon = strlen(cfg);
1652        part = (char*) malloc(lon);
1653        TomaParticiones(cfg, part, lon);
1654        sprintf(sqlstr,
1655                        "SELECT idparticion FROM particiones WHERE particion LIKE '%s'",
1656                        part);
1657        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1658                db.GetErrorErrStr(ErrStr);
1659                pthread_mutex_unlock(&guardia);
1660                return (false);
1661        }
1662        if (!tbl.ISEOF()) { // Configuración ya existente
1663                if (!tbl.Get("idparticion", idparticion)) { // Toma dato
1664                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1665                        pthread_mutex_unlock(&guardia);
1666                        return (false);
1667                }
1668        } else { // Nueva partición
1669                sprintf(sqlstr, "INSERT particiones (particion) VALUES('%s')", part);
1670                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
1671                        db.GetErrorErrStr(ErrStr);
1672                        pthread_mutex_unlock(&guardia);
1673                        return (false);
1674                }
1675                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
1676                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1677                        db.GetErrorErrStr(ErrStr);
1678                        pthread_mutex_unlock(&guardia);
1679                        return (false);
1680                }
1681                if (!tbl.ISEOF()) { // Si existe registro
1682                        if (!tbl.Get("identificador", idparticion)) {
1683                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1684                                pthread_mutex_unlock(&guardia);
1685                                return (false);
1686                        }
1687                }
1688        }
1689        if (idconfiguracion != idcfgo || idparticion != idprto) { // Si el odenador tiene una configuración distinta ...
1690                sprintf(
1691                                sqlstr,
1692                                "Update ordenadores set idconfiguracion=%d, idparticion=%d WHERE ip='%s'",
1693                                idconfiguracion, idparticion, ipho);
1694                if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
1695                        db.GetErrorErrStr(ErrStr);
1696                        pthread_mutex_unlock(&guardia);
1697                        return (false);
1698                }
1699        }
1700        pthread_mutex_unlock(&guardia);
1701        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1702        return (true);
1703}
1704// ________________________________________________________________________________________________________
1705// Función: TomaParticiones
1706//
1707//              Descripción:
1708//                      Esta función compone basándose en la cadena de configuración que devuelve el ordenador, una cadena de particiones con
1709//                      los valores "n0=PPPP;n1=PPPP..."  con las duplas:el número de partición y el tipo, separados por coma
1710//              Parámetros:
1711//                      - cfg: Cadena de configuración
1712//                      - parts: Cadena devuelta con el formato anterior descrito
1713//                      - lonprt: Longitud mínima para las cadenas
1714// ________________________________________________________________________________________________________
1715void TomaParticiones(char* cfg, char* parts, int lonprt) {
1716        int i;
1717        int lon = 0;
1718        char *tbParticiones[10]; // Para albergar hasta 10 particiones ( Normalmente Mínimo 8);
1719        char *tbParticion[8]; // Para albergar hasta 8 parámetros de partición;
1720        char *tbIgualdad[2]; // Para albergar hasta 8 parámetros de partición;
1721        char ch[2]; // Carácter delimitador
1722        char *apun;
1723        int p;
1724        // Toma memoria para cada elemento de partición
1725        for (i = 0; i < 10; i++)
1726                tbParticiones[i] = (char*) malloc(lonprt);
1727
1728        // Toma memoria para cada parámetro de partición
1729        for (i = 0; i < 8; i++)
1730                tbParticion[i] = (char*) malloc(lonprt);
1731
1732        // Toma memoria para cada igualdad
1733        for (i = 0; i < 2; i++)
1734                tbIgualdad[i] = (char*) malloc(20);
1735
1736        // Trocea la cadena de configuración
1737        strcpy(ch, "\t");// carácter delimitador (tabulador)
1738        lonprt = split_parametros(tbParticiones, cfg, ch);
1739        // Trocea las cadenas de parametros de particin
1740        for (p = 0; p < lonprt; p++) {
1741                strcpy(ch, "\n");// carácter delimitador (salto de linea)
1742                split_parametros(tbParticion, tbParticiones[p], ch);
1743                strcpy(ch, "=");// carácter delimitador "="
1744                split_parametros(tbIgualdad, tbParticion[4], ch); // Nmero de particin
1745                lon += sprintf(parts + lon, "%s=", tbIgualdad[1]);
1746                split_parametros(tbIgualdad, tbParticion[2], ch); // Tipo de particion
1747                apun = tbIgualdad[1];
1748                //if(apun[0]=='H') apun++; // Si es oculta ...
1749                lon += sprintf(parts + lon, "%s;", apun);
1750        }
1751        lon += sprintf(parts + lon, "@prt");
1752}
1753// ________________________________________________________________________________________________________
1754// Función: ComandosPendientes
1755//
1756//              Descripción:
1757//                      Esta función busca en la base de datos,comandos pendientes de ejecutar por un  ordenador  concreto
1758//              Parámetros:
1759//                      - s: Socket del cliente
1760//                      - parametros: Parámetros de la trama recibida
1761// ________________________________________________________________________________________________________
1762int ComandosPendientes(SOCKET s, char *parametros) {
1763        char *iph, *ido, *coletilla;
1764        int ids;
1765        char pids[20], ipe[16], idord[16];
1766
1767        iph = toma_parametro("iph", parametros); // Toma ip
1768        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
1769        strcpy(ipe, iph);
1770        strcpy(idord, ido);
1771
1772        if (busca_comandos(ipe, idord, parametros, &ids)) {
1773                Coloca_estado(ipe, CLIENTE_OCUPADO, s);
1774                //Manda el comando pendiente
1775                coletilla = corte_iph(parametros);
1776                coletilla[0] = '\0';// Corta la trama en la ip
1777                sprintf(pids, "ids=%d\r", ids);
1778                strcat(parametros, pids); // Le añade el identificador de la acción
1779                return (manda_comando(s, parametros));
1780        }
1781        NoComandosPendientes(s); // Indica al cliente rembo que ya no hay más comandos pendientes
1782        return (true);
1783}
1784// ________________________________________________________________________________________________________
1785// Función: EjecutarItem
1786//
1787//              Descripción:
1788//                      Esta función ejecuta un item de un men concreto solicitado por algn cliente rembo
1789//              Parámetros:
1790//                      - s: Socket del cliente
1791//                      - parametros: Parámetros de la trama recibida
1792// ________________________________________________________________________________________________________
1793int EjecutarItem(SOCKET s, char *parametros) {
1794        char sqlstr[1000], ErrStr[200];
1795        Database db;
1796        Table tbl, tbln;
1797        int idtipoaccion, lon, cont_comandos = 0, i, puertorepo;
1798        char tipoaccion, *iph, *idt, ipe[16];
1799        char *tbComandosparametros[100];
1800
1801        iph = toma_parametro("iph", parametros); // Toma ip
1802        idt = toma_parametro("idt", parametros); // Toma idemtificador del item
1803        strcpy(ipe, iph);
1804
1805        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
1806                db.GetErrorErrStr(ErrStr);
1807                return (false);
1808        }
1809        sprintf(
1810                        sqlstr,
1811                        "SELECT acciones_menus.tipoaccion, acciones_menus.idtipoaccion FROM acciones_menus WHERE acciones_menus.idaccionmenu=%s",
1812                        idt);
1813        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1814                db.GetErrorErrStr(ErrStr);
1815                return (false);
1816        }
1817        if (tbl.ISEOF()) {
1818                return (false); // No hay comandos pendientes
1819        }
1820
1821        if (!tbl.Get("tipoaccion", tipoaccion)) { // Toma dato
1822                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1823                return (false);
1824        }
1825
1826        if (!tbl.Get("idtipoaccion", idtipoaccion)) { // Toma dato
1827                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1828                return (false);
1829        }
1830
1831        switch (tipoaccion) {
1832        case EJECUCION_PROCEDIMIENTO:
1833                sprintf(
1834                                sqlstr,
1835                                "SELECT  procedimientos_comandos.parametros  FROM  procedimientos_comandos  WHERE procedimientos_comandos.idprocedimiento=%d",
1836                                idtipoaccion);
1837                if (!db.Execute(sqlstr, tbl)) { // Error al leer
1838                        db.GetErrorErrStr(ErrStr);
1839                        return (false);
1840                }
1841                if (tbl.ISEOF()) // No existe procedimiento
1842                        return (false);
1843
1844                while (!tbl.ISEOF()) {
1845                        if (!tbl.Get("parametros", parametros)) { // Toma dato
1846                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
1847                                return (false);
1848                        }
1849                        lon = strlen(parametros);
1850                        tbComandosparametros[cont_comandos] = (char*) malloc(lon);
1851                        if (tbComandosparametros[cont_comandos] == NULL)
1852                                return (false); // No hay memoria bastante
1853                        strcpy(tbComandosparametros[cont_comandos++], parametros);
1854                        tbl.MoveNext();
1855                }
1856                strcpy(parametros, tbComandosparametros[0]);
1857                strcat(parametros, "iph=");
1858                strcat(parametros, ipe);
1859                strcat(parametros, "\r");
1860                for (i = 1; i < cont_comandos; i++) {
1861                        strcat(parametros, "\n");
1862                        strcat(parametros, tbComandosparametros[i]);
1863                        strcat(parametros, "iph=");
1864                        strcat(parametros, ipe);
1865                        strcat(parametros, "\r");
1866                }
1867                if (TomaIPServidorRembo(ipe, &puertorepo))
1868                        return (manda_trama_servidorrembo(ipe, parametros, puertorepo));
1869                break;
1870        case EJECUCION_TAREA:
1871                EjecutarTarea(idtipoaccion, 0, 0, 0, db, parametros);
1872                break;
1873        case EJECUCION_TRABAJO:
1874                EjecutarTrabajo(idtipoaccion, db, parametros); // Es una programación de un trabajo
1875                break;
1876        }
1877        db.Close();
1878        return (true);
1879}
1880// ________________________________________________________________________________________________________
1881// Función: DisponibilidadComandos
1882//
1883//              Descripción:
1884//                      Esta función habilita a un clinte rembo para recibir o no, comandos iteractivos
1885//              Parámetros:
1886//                      - s: Socket del cliente
1887//                      - parametros: Parámetros de la trama recibida
1888// ________________________________________________________________________________________________________
1889int DisponibilidadComandos(SOCKET s, char *parametros) {
1890        char *iph, *swd;
1891        int resul = 0, i;
1892
1893        iph = toma_parametro("iph", parametros); // Toma ip
1894        swd = toma_parametro("swd", parametros); // Toma switch de diponibilidad
1895
1896        if (strcmp(swd, "1") == 0) // Cliente disponible
1897                resul = Coloca_estado(iph, CLIENTE_REMBO, s);
1898        else {
1899                if (cliente_existente(iph, &i)) // Si ya existe la IP ...
1900                        resul = borra_entrada(i); // Cliente apagado
1901        }
1902        return (resul);
1903}
1904// ________________________________________________________________________________________________________
1905// Función: Coloca_estado
1906//
1907//              Descripción:
1908//                      Esta función coloca el estado de un ordenador en la tabla de sockets
1909//              Parámetros:
1910//                      - iph: Ip del ordenador
1911//                      - e: Nuevo estado
1912//                      - s: Socket usado por el cliente para comunicarse con el servidor HIDRA
1913// ________________________________________________________________________________________________________
1914int Coloca_estado(char *iph, const char *e, SOCKET s) {
1915        int i;
1916        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
1917                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
1918                        if (IgualIP(iph, tbsockets[i].ip)) { // Si existe la IP en la cadena
1919                                strcpy(tbsockets[i].estado, e); // Cambia el estado
1920                                tbsockets[i].sock = s; // Guarda el socket
1921                                return (true);
1922                        }
1923                }
1924        }
1925        return (false);
1926}
1927
1928// ________________________________________________________________________________________________________
1929// Función: inclusion_srvRMB
1930//
1931//              Descripción:
1932//                      Esta funcin incorpora el socket de un nuevo servidor rembo a la tabla de sockets
1933//              Parámetros:
1934//                      - iphsrvrmb: Ip del servidor
1935//                      - puertorepo: Puerto del repositorio
1936// ________________________________________________________________________________________________________
1937int inclusion_srvRMB(char *iphsrvrmb, int puertorepo) {
1938        int i, idx;
1939
1940        // Incluyendo al cliente en la tabla de sokets
1941        if (servidorrembo_existente(iphsrvrmb, &i)) { // Si ya existe la IP ...
1942                idx = i;
1943        } else {
1944                if (hay_huecoservidorrembo(&i)) { // Busca hueco para el nuevo cliente
1945                        idx = i;
1946                        strcpy(tbsocketsSRVRMB[idx].ip, iphsrvrmb);// Copia IP
1947                        tbsocketsSRVRMB[idx].puertorepo = puertorepo;
1948                } else
1949                        return (false); // No hay huecos
1950        }
1951        return (true);
1952}
1953// ________________________________________________________________________________________________________
1954// Función: inclusion_cliWINLNX
1955//
1956//               Descripción:
1957//                      Esta función incorpora el socket de un nuevo cliente rembo a la tabla de sockets
1958//              Parámetros:
1959//                      - s: Socket del servidor rembo
1960//                      - parametros: Parámetros de la trama recibida
1961// ________________________________________________________________________________________________________
1962int inclusion_cliWINLNX(SOCKET s, char *parametros) {
1963        char *iph, *tso;
1964        int i, idx;
1965
1966        // Toma parámetros
1967        iph = toma_parametro("iph", parametros); // Toma ip
1968        tso = toma_parametro("tso", parametros); // Toma ip
1969        // Incluyendo al cliente en la tabla de sokets
1970        if (cliente_existente(iph, &i)) { // Si ya existe la IP ...
1971                idx = i;
1972                close(tbsockets[idx].sock);
1973        } else {
1974                if (hay_hueco(&i)) { // Busca hueco para el nuevo cliente
1975                        idx = i;
1976                        strcpy(tbsockets[idx].ip, iph);// Copia IP
1977                } else
1978                        return (false); // No hay huecos
1979        }
1980        tbsockets[idx].sock = s; // Guarda el socket
1981        strcpy(tbsockets[idx].estado, tso);
1982        return (true);
1983}
1984// ________________________________________________________________________________________________________
1985// Función: inclusion_REPO
1986//
1987//               Descripción:
1988//                      Esta función incorpora el socket de un nuevo repositorio hidra
1989//              Parámetros:
1990//                      - s: Socket del servidor rembo
1991//                      - parametros: Parámetros de la trama recibida
1992// ________________________________________________________________________________________________________
1993int inclusion_REPO(SOCKET s, char *parametros) {
1994        char ErrStr[200], sqlstr[1000];
1995        Database db;
1996        Table tbl;
1997
1998        char *iph;
1999        char PathHidra[250], PathPXE[250]; // path al directorio base de Hidra
2000        int puertorepo, lon;
2001
2002        // Toma parnetros
2003        iph = toma_parametro("iph", parametros); // Toma ip
2004
2005        // Toma las propiedades del ordenador
2006        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2007                db.GetErrorErrStr(ErrStr);
2008                return (false);
2009        }
2010        // Recupera los datos del ordenador
2011        sprintf(
2012                        sqlstr,
2013                        "SELECT puertorepo,pathrembod,pathpxe FROM servidoresrembo WHERE ip = '%s'",
2014                        iph);
2015
2016        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2017                db.GetErrorErrStr(ErrStr);
2018                return (false);
2019        }
2020        if (tbl.ISEOF()) { // Si No existe registro
2021                RegistraLog("No existe el Repositorio, se rechaza la petición", false);
2022                return (false);
2023        }
2024        if (!tbl.Get("puertorepo", puertorepo)) { // Toma dato
2025                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
2026                return (false);
2027        }
2028        if (!tbl.Get("pathrembod", PathHidra)) { // Toma dato
2029                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
2030                return (false);
2031        }
2032        if (!tbl.Get("pathpxe", PathPXE)) { // Toma dato
2033                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
2034                return (false);
2035        }
2036        inclusion_srvRMB(iph, puertorepo); // Actualiza tabla de servidores rembo
2037        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
2038        if (!trama)
2039                return (false);
2040        // envíala trama
2041
2042        trama->arroba = '@';
2043        strncpy(trama->identificador, "JMMLCAMDJ", 9);
2044        trama->ejecutor = '1';
2045        lon = sprintf(trama->parametros, "nfn=RESPUESTA_inclusionREPO\r");
2046        lon += sprintf(trama->parametros + lon, "prp=%d\r", puertorepo);
2047        lon += sprintf(trama->parametros + lon, "pth=%s\r", PathHidra);
2048        lon += sprintf(trama->parametros + lon, "ptx=%s\r", PathPXE);
2049        lon += sprintf(trama->parametros + lon, "usu=%s\r", usuario);
2050        lon += sprintf(trama->parametros + lon, "pwd=%s\r", pasguor);
2051        lon += sprintf(trama->parametros + lon, "dat=%s\r", datasource);
2052        lon += sprintf(trama->parametros + lon, "cat=%s\r", catalog);
2053        return (manda_trama(s, trama));
2054}
2055// ________________________________________________________________________________________________________
2056// Función: EcoConsola
2057//
2058//              Descripción:
2059//                      Esta función devuelve el eco de una consola remota
2060//              Parámetros:
2061//                      - s: Socket del servidor web que envía el comando
2062//                      - parametros: Parámetros de la trama enviada
2063// ________________________________________________________________________________________________________
2064int EcoConsola(SOCKET s, char *parametros) {
2065
2066        char *iph, *pfe, ipr[16];
2067        char nomfilesrc[512], nomfiledst[512], rep[16];
2068
2069        iph = toma_parametro("iph", parametros); // Toma ip
2070        pfe = toma_parametro("pfe", parametros); // Toma path al archivo de eco
2071
2072        if (!tomaIpRepoPort(iph, ipr, rep)) {
2073                close(s); //NO se ha podido recuperar el repositorio del ordenador
2074                return (false);
2075        }
2076        sprintf(nomfilesrc, "%s/eco-%s", pfe, iph); // Nombre del fichero destino
2077        sprintf(nomfiledst, "/tmp/eco-%s", iph); // Nombre del fichero destino
2078        if (!recibeFichero(ipr, rep, nomfilesrc, nomfiledst)) {
2079                return (enviaEcoConsola(s, "Sin eco o error de sintaxis")); // NO se ha podido recuperar el fichero de eco
2080        }
2081        // Lee archivo de eco
2082        FILE *Finv;
2083        char *buffer;
2084        long lSize;
2085        Finv = fopen(nomfiledst, "rt");
2086        fseek(Finv, 0, SEEK_END); // Obtiene tamaño del fichero.
2087        lSize = ftell(Finv);
2088        rewind(Finv);
2089        if (lSize > 0) {
2090                buffer = (char*) malloc(lSize + 1); // Toma memoria para el buffer de lectura.
2091                if (buffer == NULL) {
2092                        sprintf(
2093                                        msglog,
2094                                        "NO se ha podido reservar memoria para leer archivo de eco %s",
2095                                        nomfilesrc);
2096                        RegistraLog(msglog, false);
2097                        return (enviaEcoConsola(s, msglog));
2098                }
2099                fread(buffer, 1, lSize, Finv); // Lee contenido del fichero
2100                fclose(Finv);
2101                buffer[lSize] = '\0';
2102                buffer = escaparComillas(buffer);
2103                return (enviaEcoConsola(s, buffer));
2104        }
2105        return (enviaEcoConsola(s, "Sin eco o error de sintaxis"));
2106        return (true);
2107}
2108// ________________________________________________________________________________________________________
2109// Función: enviaEcoConsola
2110//
2111//              Descripción:
2112//                      Envía eco a la consola
2113//              Parámetros:
2114//                      - s: Socket del servidor web que envía el comando
2115//                      - eco: Salida de consola
2116// ________________________________________________________________________________________________________
2117int enviaEcoConsola(SOCKET s, const char *eco) {
2118        char nwparametros[LONGITUD_PARAMETROS];
2119        int res;
2120
2121        nwparametros[0] = '\0';
2122        strcat(nwparametros, "eco="); // Compone retorno eco (Pantalla de consola remota)
2123        strcat(nwparametros, eco);
2124        res = manda_comando(s, nwparametros);
2125        close(s);
2126        return (res);
2127}
2128// ________________________________________________________________________________________________________
2129// Función: Sondeo
2130//
2131//              Descripción:
2132//                      Esta función recupera el estado de los ordenadores solicitados
2133//              Parámetros:
2134//                      - s: Socket del servidor web que envn el comando
2135//                      - parametros: Parámetros de la trama enviada
2136// ________________________________________________________________________________________________________
2137int Sondeo(SOCKET s, char *parametros) {
2138        char *iph;
2139        char nwparametros[LONGITUD_PARAMETROS];
2140        int j;
2141
2142        iph = toma_parametro("iph", parametros); // Toma ip
2143        nwparametros[0] = '\0';
2144        strcat(nwparametros, "tso="); // Compone retorno tso ( sistemas operativos de los clientes )
2145        for (j = 0; j < MAXIMOS_SOCKETS; j++) {
2146                if (strncmp(tbsockets[j].ip, "\0", 1) != 0) { // Si es un cliente activo
2147                        if (IgualIP(iph, tbsockets[j].ip)) { // Si existe la IP en la cadena
2148                                strcat(nwparametros, tbsockets[j].ip); // Compone retorno
2149                                strcat(nwparametros, "/"); // "ip=sistemaoperatico;"
2150                                strcat(nwparametros, tbsockets[j].estado);
2151                                strcat(nwparametros, ";");
2152                        }
2153                }
2154        }
2155        return (manda_comando(s, nwparametros));
2156}
2157// ________________________________________________________________________________________________________
2158// Función: Actualizar
2159//
2160//              Descripción:
2161//                      Esta función actualiza la vista de ordenadores
2162//              Parámetros:
2163//                      - parametros: parámetros del comando
2164// ________________________________________________________________________________________________________
2165int Actualizar(char *parametros) {
2166        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
2167        if (!trama)
2168                return (false);
2169        int i, estado_cliente, lon;
2170        char *iph, *rmb;
2171
2172        iph = toma_parametro("iph", parametros); // Toma ip
2173        rmb = toma_parametro("rmb", parametros); // Toma ipe del servidor rembo
2174        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
2175                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
2176                        if (IgualIP(iph, tbsockets[i].ip)) { // Si existe la IP en la cadena
2177                                estado_cliente = strcmp(tbsockets[i].estado, CLIENTE_OCUPADO);
2178                                if (estado_cliente != 0) { // Cliente NO OCUPADO ...
2179                                        estado_cliente = strcmp(tbsockets[i].estado,
2180                                                        CLIENTE_INICIANDO);
2181                                        if (estado_cliente != 0) { // Cliente NO INICIANDO ...
2182                                                estado_cliente = strcmp(tbsockets[i].estado,
2183                                                                CLIENTE_REMBO);
2184                                                if (estado_cliente != 0) { // Cliente windows o linux ...
2185                                                        lon
2186                                                                        = sprintf(trama->parametros,
2187                                                                                        "nfn=Actualizar\r");
2188                                                        manda_comando(tbsockets[i].sock,
2189                                                                        (char*) trama->parametros);
2190                                                }
2191                                                borra_entrada(i);
2192                                        }
2193                                }
2194                        }
2195                }
2196        }
2197        int j;
2198        for (j = 0; j < MAXIMOS_SRVRMB; j++) {
2199                if (strcmp(rmb, tbsocketsSRVRMB[j].ip) == 0) { // Si existe la IP ...
2200                        FINCADaINTRO(parametros, iph);
2201                        return (manda_trama_servidorrembo(rmb, parametros,
2202                                        tbsocketsSRVRMB[j].puertorepo));
2203                }
2204        }
2205        return (false);
2206}
2207// ________________________________________________________________________________________________________
2208// Función: ConsolaRemota
2209//
2210//              Descripción:
2211//                      Esta función implementa la consola remota
2212//              Parámetros:
2213//                      - parametros: parámetros del comando
2214// ________________________________________________________________________________________________________
2215int ConsolaRemota(char *parametros) {
2216        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
2217        if (!trama)
2218                return (false);
2219        int i, estado_cliente, lon;
2220        char *iph, *rmb;
2221
2222        iph = toma_parametro("iph", parametros); // Toma ip
2223        rmb = toma_parametro("rmb", parametros); // Toma ipe del servidor rembo
2224        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
2225                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
2226                        if (IgualIP(iph, tbsockets[i].ip)) { // Si existe la IP en la cadena
2227                                estado_cliente = strcmp(tbsockets[i].estado, CLIENTE_OCUPADO);
2228                                if (estado_cliente != 0) { // Cliente NO OCUPADO ...
2229                                        estado_cliente = strcmp(tbsockets[i].estado,
2230                                                        CLIENTE_INICIANDO);
2231                                        if (estado_cliente != 0) { // Cliente NO INICIANDO ...
2232                                                estado_cliente = strcmp(tbsockets[i].estado,
2233                                                                CLIENTE_REMBO);
2234                                                if (estado_cliente != 0) { // Cliente windows o linux ...
2235                                                        lon = sprintf(trama->parametros,
2236                                                                        "nfn=ConsolaRemota\r");
2237                                                        manda_comando(tbsockets[i].sock,
2238                                                                        (char*) trama->parametros);
2239                                                }
2240                                        }
2241                                }
2242                        }
2243                }
2244        }
2245        int j;
2246        for (j = 0; j < MAXIMOS_SRVRMB; j++) {
2247                if (strcmp(rmb, tbsocketsSRVRMB[j].ip) == 0) { // Si existe la IP ...
2248                        FINCADaINTRO(parametros, iph);
2249                        return (manda_trama_servidorrembo(rmb, parametros,
2250                                        tbsocketsSRVRMB[j].puertorepo));
2251                }
2252        }
2253        return (false);
2254}
2255// ________________________________________________________________________________________________________
2256// Función: FicheroOperador
2257//
2258//              Descripción:
2259//                      Esta función envía al servidor datos de un operador para crear fichero de login
2260//              Parámetros:
2261//                      - parametros: parámetros del comando
2262// ________________________________________________________________________________________________________
2263int FicheroOperador(char *parametros) {
2264        TRAMA trama;
2265        SOCKET s;
2266        char *rmb, *amb, *usu, *psw, *ida;
2267        int resul, lon;
2268
2269        rmb = toma_parametro("rmb", parametros); // Toma ipe del servidor rembo
2270
2271        // Abre conexion con el servidor rembo y envíatrama
2272        s = AbreConexion(rmb, puerto + 1);
2273        if (!s) {
2274                RegistraLog(
2275                                "Fallo al conectar con el servidor rembo para envio de tramas",
2276                                true);
2277                return (FALSE);
2278        }
2279
2280        amb = toma_parametro("amb", parametros); // Toma tipo de operacion
2281        usu = toma_parametro("usu", parametros); // Toma usuario
2282        psw = toma_parametro("psw", parametros); // Toma passwrod
2283        ida = toma_parametro("ida", parametros); // Toma identificador del aula
2284
2285        // envíala trama
2286        trama.arroba = '@';
2287        strncpy(trama.identificador, "JMMLCAMDJ", 9);
2288        trama.ejecutor = '1';
2289        lon = sprintf(trama.parametros, "nfn=FicheroOperador\r");
2290        lon += sprintf(trama.parametros + lon, "amb=%s\r", amb);
2291        lon += sprintf(trama.parametros + lon, "usu=%s\r", usu);
2292        lon += sprintf(trama.parametros + lon, "psw=%s\r", psw);
2293        lon += sprintf(trama.parametros + lon, "ida=%s\r", ida);
2294        resul = (manda_trama(s, &trama));
2295        if (!resul)
2296                RegistraLog("Fallo en el envio de trama al servidor rembo", true);
2297        return (resul);
2298}
2299// ________________________________________________________________________________________________________
2300// Función: Conmutar
2301//
2302//              Descripción:
2303//                      Esta función conmuta un cliente rembo del modo NO administrado al modo admnistrado
2304//              Parámetros:
2305//                      - parametros: parámetros del comando
2306// ________________________________________________________________________________________________________
2307int Conmutar(char *parametros) {
2308        TRAMA trama;
2309        SOCKET s;
2310        int i, estado_cliente, lon, resul;
2311        char *iph, *rmb;
2312
2313        iph = toma_parametro("iph", parametros); // Toma ip
2314        rmb = toma_parametro("rmb", parametros); // Toma ipe del servidor rembo
2315        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
2316                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
2317                        if (IgualIP(iph, tbsockets[i].ip)) { // Si existe la IP en la cadena
2318                                estado_cliente = strcmp(tbsockets[i].estado, CLIENTE_OCUPADO);
2319                                if (estado_cliente != 0) { // Cliente NO OCUPADO ...
2320                                        estado_cliente = strcmp(tbsockets[i].estado,
2321                                                        CLIENTE_INICIANDO);
2322                                        if (estado_cliente != 0) { // Cliente NO INICIANDO ...
2323                                                estado_cliente = strcmp(tbsockets[i].estado,
2324                                                                CLIENTE_REMBO);
2325                                                if (estado_cliente != 0) { // Cliente windows o linux ...
2326                                                        lon = sprintf(trama.parametros, "nfn=Conmutar\r");
2327                                                        manda_comando(tbsockets[i].sock, trama.parametros);
2328                                                }
2329                                        }
2330                                }
2331                        }
2332                }
2333        }
2334
2335        // Abre conexión con el servidor rembo y envíatrama
2336        s = AbreConexion(rmb, puerto + 1);
2337        if (!s) {
2338                RegistraLog(
2339                                "Fallo al conectar con el servidor rembo para envio de tramas",
2340                                true);
2341                resul = FALSE;
2342        } else {
2343                // Envía la trama
2344                trama.arroba = '@';
2345                strncpy(trama.identificador, "JMMLCAMDJ", 9);
2346                trama.ejecutor = '2';
2347                lon = sprintf(trama.parametros, "nfn=Conmutar\r");
2348                lon += sprintf(trama.parametros + lon, "iph=%s\r", iph);
2349                resul = (manda_trama(s, &trama));
2350                if (!resul) {
2351                        RegistraLog("Fallo en el envio de trama al servidor rembo", true);
2352                }
2353        }
2354        return (resul);
2355}
2356// ________________________________________________________________________________________________________
2357// Función: PurgarTablaSockets
2358//
2359//              Descripción:
2360//                      Borra ordenadores de la tabla de sockets
2361//              Parámetros:
2362//                      - parametros: parámetros del comando
2363// ________________________________________________________________________________________________________
2364void PurgarTablaSockets(char *parametros) {
2365        int i;
2366        char *iph;
2367
2368        iph = toma_parametro("iph", parametros); // Toma ip
2369        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
2370                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
2371                        if (IgualIP(iph, tbsockets[i].ip)) { // Si existe la IP en la cadena
2372                                borra_entrada(i);
2373                        }
2374                }
2375        }
2376}
2377// _____________________________________________________________________________________________________________
2378// Función: Arrancar
2379//
2380//              Descripción:
2381//                      Esta función arranca los ordenadores solicitados. PAra ello le envía el comando arrancar al servidor rembo que lo controla y
2382//                      es éste el que le envía la trama de wake-up
2383//              Parámetros:
2384//                      - parametros: parámetros del comando
2385// _____________________________________________________________________________________________________________
2386int Arrancar(char *parametros) {
2387        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
2388        if (!trama)
2389                return (false);
2390        char *iph, *rmb, *mac;
2391        int j;
2392
2393        rmb = toma_parametro("rmb", parametros);
2394        mac = toma_parametro("mac", parametros);
2395        iph = toma_parametro("iph", parametros);
2396
2397        for (j = 0; j < MAXIMOS_SRVRMB; j++) {
2398                if (strcmp(rmb, tbsocketsSRVRMB[j].ip) == 0) { // Si existe la IP ...
2399                        FINCADaINTRO(parametros, iph);
2400                        return (manda_trama_servidorrembo(rmb, parametros,
2401                                        tbsocketsSRVRMB[j].puertorepo));
2402                }
2403        }
2404        return (false);
2405}
2406// ________________________________________________________________________________________________________
2407// Función: RESPUESTA_Arrancar
2408//
2409//              Descripción:
2410//                      Responde al comando Apagar
2411//              Parámetros:
2412//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2413//                      - parametros: parámetros del comando
2414// ________________________________________________________________________________________________________
2415int RESPUESTA_Arrancar(SOCKET s, char *parametros) {
2416        char ErrStr[200];
2417        Database db;
2418        Table tbl;
2419
2420        char *res, *der, *iph, *ido, *ids;
2421
2422        res = toma_parametro("res", parametros); // Toma resultado
2423        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2424        iph = toma_parametro("iph", parametros); // Toma ip
2425        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2426        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
2427
2428        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2429                db.GetErrorErrStr(ErrStr);
2430                return (false);
2431        }
2432        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2433                return (false); // Error al registrar notificación
2434        }
2435        db.Close();
2436        return (true);
2437}
2438// ________________________________________________________________________________________________________
2439// Función: RESPUESTA_Apagar
2440//
2441//              Descripción:
2442//                      Responde al comando Apagar
2443//              Parámetros:
2444//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2445//                      - parametros: parametros del comando
2446// ________________________________________________________________________________________________________
2447int RESPUESTA_Apagar(SOCKET s, char *parametros) {
2448        char ErrStr[200];
2449        Database db;
2450        Table tbl;
2451        int i;
2452        char *res, *der, *iph, *ido, *ids;
2453
2454        res = toma_parametro("res", parametros); // Toma resultado
2455        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2456        iph = toma_parametro("iph", parametros); // Toma ip
2457        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2458        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
2459
2460        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2461                db.GetErrorErrStr(ErrStr);
2462                return (false);
2463        }
2464        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2465                return (false); // Error al registrar notificación
2466        }
2467
2468        if (strcmp(res, ACCION_FALLIDA) == 0)
2469                return (TRUE); // Error en la ejecución de la acción en el cliente rembo
2470
2471        if (cliente_existente(iph, &i)) // Si ya existe la IP ...
2472                borra_entrada(i);
2473        db.Close();
2474        return (true);
2475}
2476// ________________________________________________________________________________________________________
2477// Función: RESPUESTA_Reiniciar
2478//
2479//              Descripción:
2480//                      Responde al comando Reiniciar
2481//              Parámetros:
2482//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2483//                      - parametros: parametros del comando
2484// ________________________________________________________________________________________________________
2485int RESPUESTA_Reiniciar(SOCKET s, char *parametros) {
2486        int i;
2487        char ErrStr[200];
2488        Database db;
2489        Table tbl;
2490
2491        char *res, *der, *iph, *ido, *ids;
2492
2493        res = toma_parametro("res", parametros); // Toma resultado
2494        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2495        iph = toma_parametro("iph", parametros); // Toma ip
2496        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2497        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
2498
2499        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2500                db.GetErrorErrStr(ErrStr);
2501                return (false);
2502        }
2503        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2504                return (false); // Error al registrar notificación
2505        }
2506        if (strcmp(res, ACCION_FALLIDA) == 0)
2507                return (TRUE); // Error en la ejecucin de la acción en el cliente rembo
2508
2509        if (cliente_existente(iph, &i)) // Si ya existe la IP ...
2510                borra_entrada(i);
2511        db.Close();
2512        return (true);
2513}
2514// ________________________________________________________________________________________________________
2515// Función: RESPUESTA_IniciarSesion
2516//
2517//              Descripción:
2518//                      Responde al comando Iniciar sesión
2519//              Parámetros:
2520//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2521//                      - parametros: parametros del comando
2522// ________________________________________________________________________________________________________
2523int RESPUESTA_IniciarSesion(SOCKET s, char *parametros) {
2524        char ErrStr[200];
2525        Database db;
2526        Table tbl;
2527        int i;
2528        char *res, *der, *iph, *ido, *ids;
2529
2530        res = toma_parametro("res", parametros); // Toma resultado
2531        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2532        iph = toma_parametro("iph", parametros); // Toma ip
2533        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2534        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
2535
2536        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2537                db.GetErrorErrStr(ErrStr);
2538                return (false);
2539        }
2540        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2541                return (false); // Error al registrar notificación
2542        }
2543
2544        if (strcmp(res, ACCION_FALLIDA) == 0)
2545                return (TRUE); // Error en la ejecucin de la acción en el cliente rembo
2546
2547        if (cliente_existente(iph, &i)) // Si ya existe la IP ...
2548                borra_entrada(i);
2549        db.Close();
2550        return (true);
2551}
2552// ________________________________________________________________________________________________________
2553//
2554// Función: borra_entrada
2555//
2556//              Descripción:
2557//                       Borra la entrada de un ordenador en la tabla de socket
2558//              Parámetros:
2559//                      - i: Indice dentro de la tabla
2560// ________________________________________________________________________________________________________
2561int borra_entrada(int i) {
2562        tbsockets[i].ip[0] = (char) NULL;
2563        tbsockets[i].estado[0] = (char) NULL;
2564        if (!tbsockets[i].sock)
2565                close(tbsockets[i].sock);
2566        tbsockets[i].sock = INVALID_SOCKET;
2567        //tbsockets[i].ipsrvdhcp[0]=(char)NULL;
2568        tbsockets[i].ipsrvrmb[0] = (char) NULL;
2569
2570        return (true);
2571}
2572// ________________________________________________________________________________________________________
2573// Función: RESPUESTA_ExecShell
2574//
2575//              Descripción:
2576//                      Responde al comando Ejecutar script
2577//              Parámetros:
2578//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2579//                      - parametros: parametros del comando
2580// ________________________________________________________________________________________________________
2581int RESPUESTA_ExecShell(SOCKET s, char *parametros) {
2582        char ErrStr[200];
2583        Database db;
2584        Table tbl;
2585
2586        char *res, *der, *ids, *iph, *ido, *cfg;
2587
2588        res = toma_parametro("res", parametros); // Toma resultado
2589        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2590        ids = toma_parametro("ids", parametros); // Toma idperfilsoft
2591        iph = toma_parametro("iph", parametros); // Toma ip
2592        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2593        cfg = toma_parametro("cfg", parametros); // Toma configuracin
2594
2595        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2596                db.GetErrorErrStr(ErrStr);
2597                return (false);
2598        }
2599        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2600                return (false); // Error al registrar notificación
2601        }
2602
2603        if (strcmp(res, ACCION_FALLIDA) != 0) { // Ha habido algún error en la ejecución de la acción del cliente rembo
2604                if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph)) // El ordenador ha cambiado de configuración
2605                        return (false);
2606        }
2607        db.Close();
2608        return (true);
2609}
2610// ________________________________________________________________________________________________________
2611// Función: RespuestaEstandar
2612//
2613//              Descripción:
2614//                      Esta función actualiza la base de datos con el resultado de la ejecución de un comando con seguimiento
2615//              Parámetros:
2616//                      - res: resultado de la ejecucin del comando
2617//                      - der: Descripción del error si hubiese habido
2618//                      - ids: identificador de la acción notificada
2619//                      - ido: Identificador del ordenador que notifica
2620//                      - db: Objeto base de datos (operativo)
2621//                      - tbl: Objeto tabla
2622// ________________________________________________________________________________________________________
2623int RespuestaEstandar(char *res, char *der, char *ids, char* ido, Database db,
2624                Table tbl) {
2625        char ErrStr[200], sqlstr[1000];
2626        char parametros[LONGITUD_PARAMETROS];
2627        char fechareg[100];
2628        int i, resul;
2629        int idaccion, accionid, idnotificador;
2630        char *iph;
2631        struct tm* st;
2632
2633        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2634        // ACCESO único A TRAVES DE OBJETO MUTEX a este trozo de código
2635        pthread_mutex_lock(&guardia);
2636
2637        sprintf(sqlstr, "Select * from acciones WHERE idaccion=%s", ids);
2638        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2639                db.GetErrorErrStr(ErrStr);
2640                pthread_mutex_unlock(&guardia);
2641                return (false);
2642        }
2643        if (tbl.ISEOF()) { // No existe registro de acciones
2644                pthread_mutex_unlock(&guardia);
2645                return (true);
2646        }
2647        if (!tbl.Get("parametros", parametros)) { // Toma parametros de la acción
2648                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
2649                pthread_mutex_unlock(&guardia);
2650                return (false);
2651        }
2652        char resultado[2]; // comprueba si ya ha fallado la acción
2653        if (!tbl.Get("resultado", resultado)) { // Toma resultado actual de la acción
2654                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
2655                pthread_mutex_unlock(&guardia);
2656                return (false);
2657        }
2658        if (!tbl.Get("idaccion", idaccion)) { // Toma el identificador de la acción para tener el dato en formato "int"
2659                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
2660                pthread_mutex_unlock(&guardia);
2661                return (false);
2662        }
2663        if (!tbl.Get("accionid", accionid)) { // Toma la accion padre
2664                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
2665                pthread_mutex_unlock(&guardia);
2666                return (false);
2667        }
2668        if (!tbl.Get("idnotificador", idnotificador)) { // Toma el identificador del notificador
2669                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
2670                pthread_mutex_unlock(&guardia);
2671                return (false);
2672        }
2673
2674        st = TomaHora();
2675        sprintf(fechareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon + 1,
2676                        st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
2677
2678        // Graba notificación
2679        sprintf(
2680                        sqlstr,
2681                        "INSERT INTO notificaciones (accionid,idnotificador,fechahorareg,resultado,descrinotificacion) VALUES (%s,%s,'%s','%s','%s')",
2682                        ids, ido, fechareg, res, der);
2683        if (!db.Execute(sqlstr)) { // Error al insertar
2684                db.GetErrorErrStr(ErrStr);
2685                pthread_mutex_unlock(&guardia);
2686                return (false);
2687        }
2688
2689        if (strcmp(res, ACCION_FALLIDA) == 0
2690                        && strcmp(resultado, ACCION_SINERRORES) == 0) { // Accion fallida en el cliente rembo
2691                sprintf(sqlstr, "Update acciones set resultado='%s' WHERE idaccion=%s",
2692                                ACCION_CONERRORES, ids);
2693                strcpy(resultado, ACCION_CONERRORES);
2694                if (!db.Execute(sqlstr)) { // Error al actualizar
2695                        db.GetErrorErrStr(ErrStr);
2696                        pthread_mutex_unlock(&guardia);
2697                        return (false);
2698                }
2699        }
2700        // Comprueba si la acción se ejecutncorrectamente para el ambito sumando notificaciones
2701        INTROaFINCAD(parametros);
2702        iph = toma_parametro("iph", parametros); // Toma cadenaip
2703        int tbnumipes = 0, totalipes = 1, lon;
2704
2705        lon = strlen(iph);
2706        for (i = 0; i < lon; i++) {
2707                if (iph[i] == ';')
2708                        totalipes++; // ip detectada
2709        }
2710
2711        sprintf(
2712                        sqlstr,
2713                        "SELECT COUNT(*) AS tbnumipes FROM notificaciones WHERE accionid=%s",
2714                        ids);
2715        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2716                pthread_mutex_unlock(&guardia);
2717                db.GetErrorErrStr(ErrStr);
2718                pthread_mutex_unlock(&guardia);
2719                return (false);
2720        }
2721
2722        if (!tbl.Get("tbnumipes", tbnumipes)) { // Recupera el numero de ordenadores que ya han notificado
2723                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo
2724                pthread_mutex_unlock(&guardia);
2725                return (false);
2726        }
2727        if (tbnumipes != totalipes) {
2728                pthread_mutex_unlock(&guardia);
2729                return (true); // No es el ultimo ordenador en notificar
2730        }
2731
2732        st = TomaHora();
2733        sprintf(fechareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon + 1,
2734                        st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
2735
2736        // Actualización después de que todos los ordenadores han notificado
2737        if (strcmp(resultado, ACCION_SINERRORES) == 0) { // Acción finalizada con éxito
2738                sprintf(
2739                                sqlstr,
2740                                "Update acciones set estado='%s',resultado='%s',fechahorafin='%s' WHERE idaccion=%s",
2741                                ACCION_FINALIZADA, ACCION_EXITOSA, fechareg, ids);
2742                if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
2743                        db.GetErrorErrStr(ErrStr);
2744                        pthread_mutex_unlock(&guardia);
2745                        return (false);
2746                }
2747        }
2748        if (strcmp(resultado, ACCION_CONERRORES) == 0) { // Acción finalizada con errores
2749                sprintf(
2750                                sqlstr,
2751                                "Update acciones set estado='%s',resultado='%s',fechahorafin='%s' WHERE idaccion=%s",
2752                                ACCION_FINALIZADA, ACCION_FALLIDA, fechareg, ids);
2753                if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
2754                        db.GetErrorErrStr(ErrStr);
2755                        pthread_mutex_unlock(&guardia);
2756                        return (false);
2757                }
2758        }
2759        resul = true;
2760        if (accionid > 0) { // Existe acción padre que hay que actualizar
2761                resul = InsertaNotificaciones(idaccion, idnotificador, accionid,
2762                                resultado, db);
2763                if (resul)
2764                        resul = comprueba_resultados(accionid, db);
2765        }
2766        pthread_mutex_unlock(&guardia);
2767        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2768        return (resul);
2769}
2770// ________________________________________________________________________________________________________
2771// Función: RESPUESTA_CrearPerfilSoftware
2772//
2773//              Descripción:
2774//                      Responde al comando Crear Perfil Software
2775//              Parámetros:
2776//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2777//                      - parametros: parametros del comando
2778// ________________________________________________________________________________________________________
2779int RESPUESTA_CrearPerfilSoftware(SOCKET s, char *parametros) {
2780        char ErrStr[200], sqlstr[1000];
2781        char *res, *der, *ids, *ifh, *ifs, *iph, *ido;
2782        Database db;
2783        Table tbl;
2784
2785        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2786                db.GetErrorErrStr(ErrStr);
2787                return (false);
2788        }
2789
2790        res = toma_parametro("res", parametros); // Toma resultado
2791        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2792        ids = toma_parametro("ids", parametros); // Toma idperfilsoft
2793        iph = toma_parametro("iph", parametros); // Toma ip
2794        ido = toma_parametro("ido", parametros); // Toma dentificador del ordenador
2795        ifh = toma_parametro("ifh", parametros); // Toma idperfilhard
2796        ifs = toma_parametro("ifs", parametros); // Toma idperfilsoft
2797
2798        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2799                return (false); // Error al registrar notificación
2800        }
2801
2802        if (strcmp(res, ACCION_FALLIDA) == 0) { // Ha habido algún error en la ejecución de la acción en el cliente rembo
2803                db.Close();
2804                return (false);
2805        }
2806
2807        sprintf(
2808                        sqlstr,
2809                        "Select * from perfileshard_perfilessoft WHERE idperfilhard=%s AND idperfilsoft=%s",
2810                        ifh, ifs);
2811        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2812                db.GetErrorErrStr(ErrStr);
2813                return (false);
2814        }
2815        if (!tbl.ISEOF()) { // Si ya existe el registro ... no hace falta insertarlo
2816                db.Close();
2817                return (false);
2818        }
2819        sprintf(
2820                        sqlstr,
2821                        "INSERT INTO perfileshard_perfilessoft (idperfilhard,idperfilsoft) VALUES(%s,%s)",
2822                        ifh, ifs);
2823        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2824                db.GetErrorErrStr(ErrStr);
2825                return (false);
2826        }
2827        db.Close();
2828        return (true);
2829}
2830// ________________________________________________________________________________________________________
2831// Función: RESPUESTA_CrearSoftwareIncremental
2832//
2833//              Descripción:
2834//                      Esta función responde a un comando de creación de un software incremental. Además actualiza  la base de datos insertando
2835//                      en su caso la nueva combinación de perfil software con incremental.
2836//              Parámetros:
2837//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2838//                      - parametros: parametros del comando
2839// ________________________________________________________________________________________________________
2840int RESPUESTA_CrearSoftwareIncremental(SOCKET s, char *parametros) {
2841        char ErrStr[200], sqlstr[1000];
2842        char *res, *der, *ids, *ifh, *ifs, *icr, *iph, *ido;
2843        int idphardidpsoft;
2844        Database db;
2845        Table tbl;
2846
2847        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
2848                db.GetErrorErrStr(ErrStr);
2849                return (false);
2850        }
2851
2852        res = toma_parametro("res", parametros); // Toma resultado
2853        der = toma_parametro("der", parametros); // Toma descripción del error ( si hubiera habido)
2854        ids = toma_parametro("ids", parametros); // Toma idperfilsoft
2855        iph = toma_parametro("iph", parametros); // Toma ip
2856        ido = toma_parametro("ido", parametros); // Toma dentificador del ordenador
2857        ifh = toma_parametro("ifh", parametros); // Toma idperfilhard
2858        ifs = toma_parametro("ifs", parametros); // Toma idperfilsoft
2859        icr = toma_parametro("icr", parametros); // Toma idsoftincremental
2860
2861        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2862                return (false); // Error al registrar notificación
2863        }
2864
2865        if (strcmp(res, ACCION_FALLIDA) == 0) { // Ha habido algn error en la ejecución de la acción en el cliente rembo
2866                db.Close();
2867                return (false);
2868        }
2869
2870        sprintf(
2871                        sqlstr,
2872                        "Select idphardidpsoft from perfileshard_perfilessoft WHERE idperfilhard=%s AND idperfilsoft=%s",
2873                        ifh, ifs);
2874        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2875                db.GetErrorErrStr(ErrStr);
2876                return (false);
2877        }
2878
2879        if (tbl.ISEOF()) { // Si no existe el registro ...
2880                db.Close();
2881                return (false);
2882        }
2883
2884        if (!tbl.Get("idphardidpsoft", idphardidpsoft)) { // Recupera el identificador de la combinación de perfiles
2885                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo
2886                return (false);
2887        }
2888
2889        sprintf(
2890                        sqlstr,
2891                        "Select * from phard_psoft_softincremental WHERE idphardidpsoft=%d AND idsoftincremental=%s",
2892                        idphardidpsoft, icr);
2893        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2894                db.GetErrorErrStr(ErrStr);
2895                return (false);
2896        }
2897
2898        if (!tbl.ISEOF()) { // Si ya existe el registro ...
2899                db.Close();
2900                return (false);
2901        }
2902
2903        sprintf(
2904                        sqlstr,
2905                        "INSERT INTO phard_psoft_softincremental (idphardidpsoft,idsoftincremental) VALUES(%d,%s)",
2906                        idphardidpsoft, icr);
2907        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2908                db.GetErrorErrStr(ErrStr);
2909                return (false);
2910        }
2911        db.Close();
2912        return (true);
2913}
2914// ________________________________________________________________________________________________________
2915// Función: RESPUESTA_RestaurarImagen
2916//
2917//              Descripción:
2918//                      Esta función responde a un comando de restauracin de una imagen. Además actualiza la base de datos.
2919//              Parámetros:
2920//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
2921//                      - parametros: parametros del comando
2922// ________________________________________________________________________________________________________
2923int RESPUESTA_RestaurarImagen(SOCKET s, char *parametros) {
2924        char ErrStr[200], gido[20];
2925        char *res, *der, *ids, *iph, *ido, *idi, *par, *cfg;
2926        Database db;
2927        Table tbl;
2928
2929        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
2930                db.GetErrorErrStr(ErrStr);
2931                return (false);
2932        }
2933
2934        INTROaFINCAD(parametros);
2935
2936        res = toma_parametro("res", parametros); // Toma resultado
2937        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
2938        ids = toma_parametro("ids", parametros); // Toma identificador de la accion
2939        iph = toma_parametro("iph", parametros); // Toma ip
2940        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
2941        cfg = toma_parametro("cfg", parametros); // Toma configuracin
2942        par = toma_parametro("par", parametros); // particion
2943        idi = toma_parametro("idi", parametros); // identificador de la imagen
2944
2945        strcpy(gido, ido); // Guarda el identificador del ordenador
2946
2947        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2948                return (false); // Error al registrar notificacion
2949        }
2950        if (strcmp(res, ACCION_FALLIDA) == 0) { // Ha habido algn error en la ejecucin de la acción del cliente rembo
2951                db.Close();
2952                return (false);
2953        }
2954
2955        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
2956                return (false); // Erro al actualiza la configuracin
2957        if (!Actualiza_ordenador_imagen(par, idi, gido, db))
2958                return (false);
2959        db.Close();
2960        return (true);
2961}
2962// ________________________________________________________________________________________________________
2963// Función: Actualiza_ordenador_imagen
2964//
2965//              Descripción:
2966//                      Esta función actualiza la tabla ordenador_imagen
2967//              Parámetros:
2968//                      - par: partición
2969//                      - idi: identificador de la imagen ( 0 ninguna )
2970//                      - ido: identificador del ordenador
2971//                      - db: Conexión ADO operativa
2972// ________________________________________________________________________________________________________
2973int Actualiza_ordenador_imagen(char *par, const char *idi, char *ido,
2974                Database db) {
2975        char ErrStr[200], sqlstr[1000];
2976        Table tbl;
2977        int idimagen, idimagenres;
2978
2979        idimagenres = atoi(idi);
2980        if (idimagenres == 0) { // Se ha formateado la partición y se ha borrado la imagen por tanto
2981                sprintf(
2982                                sqlstr,
2983                                "DELETE FROM ordenador_imagen WHERE idordenador=%s AND particion=%s",
2984                                ido, par);
2985                if (!db.Execute(sqlstr)) { // Error al insertar
2986                        db.GetErrorErrStr(ErrStr);
2987                        return (false);
2988                }
2989                return (true);
2990        }
2991
2992        sprintf(
2993                        sqlstr,
2994                        "SELECT idimagen FROM ordenador_imagen INNER JOIN ordenadores ON ordenador_imagen.idordenador = ordenadores.idordenador WHERE ordenadores.idordenador = %s AND ordenador_imagen.particion = %s",
2995                        ido, par);
2996        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
2997                db.GetErrorErrStr(ErrStr);
2998                return (false);
2999        }
3000        if (!tbl.ISEOF()) { // Existe registro
3001                if (!tbl.Get("idimagen", idimagen)) {
3002                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3003                        return (false);
3004                } else {
3005                        if (idimagenres != idimagen) {
3006                                sprintf(
3007                                                sqlstr,
3008                                                "Update ordenador_imagen set idimagen=%s WHERE idordenador=%s AND particion=%s",
3009                                                idi, ido, par);
3010                                if (!db.Execute(sqlstr)) { // Error al actualizar
3011                                        db.GetErrorErrStr(ErrStr);
3012                                        return (false);
3013                                }
3014                        }
3015                }
3016        } else { // No existe el registro
3017                sprintf(
3018                                sqlstr,
3019                                "INSERT INTO ordenador_imagen (idordenador,particion,idimagen) VALUES(%s,%s,%s)",
3020                                ido, par, idi);
3021                if (!db.Execute(sqlstr)) { // Error al insertar
3022                        db.GetErrorErrStr(ErrStr);
3023                        return (false);
3024                }
3025        }
3026        return (true);
3027}
3028// ________________________________________________________________________________________________________
3029// Función: RESPUESTA_ParticionaryFormatear
3030//
3031//              Descripción:
3032//                      Esta función responde a un comando de particionar y formatear.  Además actualiza la base de datos.
3033//              Parámetros:
3034//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3035//                      - parametros: parametros del comando
3036// ________________________________________________________________________________________________________
3037int RESPUESTA_ParticionaryFormatear(SOCKET s, char *parametros) {
3038        char sqlstr[1000], ErrStr[200], gido[20];
3039        Database db;
3040        Table tbl;
3041        char *res, *der, *ids, *iph, *ido, *cfg;
3042
3043        res = toma_parametro("res", parametros); // Toma resultado
3044        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3045        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3046        iph = toma_parametro("iph", parametros); // Toma ip
3047        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3048        cfg = toma_parametro("cfg", parametros); // Toma configuracin
3049
3050        strcpy(gido, ido); // Guarda el identificador del ordenador
3051
3052        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
3053                db.GetErrorErrStr(ErrStr);
3054                return (false);
3055        }
3056        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3057                return (false); // Error al registrar notificacion
3058        }
3059        if (strcmp(res, ACCION_FALLIDA) == 0) {
3060                db.Close();
3061                return (true); // Ha habido algn error en la ejecucin de la acción del cliente rembo
3062        }
3063        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
3064                return (false); // Error al actualiza la configuración
3065
3066        // Elimina información sobre imagenes en este ordenador, al haber sido formateado
3067        sprintf(sqlstr, "DELETE FROM ordenador_imagen WHERE idordenador=%s", gido);
3068        if (!db.Execute(sqlstr)) { // Error al insertar
3069                db.GetErrorErrStr(ErrStr);
3070                return (false);
3071        }
3072        db.Close();
3073        return (true);
3074}
3075// ________________________________________________________________________________________________________
3076// Función: RESPUESTA_Configurar
3077//
3078//              Descripción:
3079//                      Esta función responde a un comando de Configurar. Además actualiza la base de datos.
3080//              Parámetros:
3081//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3082//                      - parametros: parámetros del comando
3083// ________________________________________________________________________________________________________
3084int RESPUESTA_Configurar(SOCKET s, char *parametros) {
3085        char ErrStr[200], gids[20], gido[20];
3086        Database db;
3087        Table tbl;
3088        int lon, resul, i;
3089        char *res, *der, *ids, *iph, *ido, *cfg, *hdc;
3090
3091        res = toma_parametro("res", parametros); // Toma resultado
3092        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3093        ids = toma_parametro("ids", parametros); // Toma idperfilsoft
3094        iph = toma_parametro("iph", parametros); // Toma ip
3095        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3096        cfg = toma_parametro("cfg", parametros); // Toma configuracin
3097        hdc = toma_parametro("hdc", parametros); // Toma participaciones a formatear
3098
3099        strcpy(gids, ids); // Guarda el identificador de la acción
3100        strcpy(gido, ido); // Guarda el identificador del ordenador
3101
3102        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
3103                db.GetErrorErrStr(ErrStr);
3104                return (false);
3105        }
3106        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3107                return (false); // Error al registrar notificacion
3108        }
3109
3110        if (strcmp(res, ACCION_FALLIDA) == 0) {
3111                db.Close();
3112                return (true); // Ha habido algn error en la ejecucin de la acción del cliente rembo
3113        }
3114        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
3115                return (false); // Error al actualiza la configuracin
3116
3117        lon = strlen(hdc);
3118        for (i = 0; i < lon; i++) {
3119                if (hdc[i] == ';')
3120                        hdc[i] = '\0';
3121        }
3122        for (i = 0; i < lon; i++) {
3123                if (*hdc != '\0') {
3124                        resul = Actualiza_ordenador_imagen(hdc, "0", gido, db);
3125                        if (!resul) {
3126                                db.Close();
3127                                return (false);
3128                        }
3129                }
3130                hdc++;
3131        }
3132        db.Close();
3133        return (true);
3134}
3135// ________________________________________________________________________________________________________
3136// Función: RESPUESTA_TomaConfiguracion
3137//
3138//              Descripción:
3139//                      Esta función responde a un comando de Toma Comfiguracin. Además actualiza la base de datos.
3140//              Parámetros:
3141//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3142//                      - parametros: parámetros del comando
3143// ________________________________________________________________________________________________________
3144int RESPUESTA_TomaConfiguracion(SOCKET s, char *parametros) {
3145        char ErrStr[200];
3146        Database db;
3147        Table tbl;
3148
3149        char *res, *der, *ids, *iph, *ido, *cfg;
3150
3151        res = toma_parametro("res", parametros); // Toma resultado
3152        der = toma_parametro("der", parametros); // Toma descripción del error ( si hubiera habido)
3153        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3154        iph = toma_parametro("iph", parametros); // Toma ip
3155        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3156        cfg = toma_parametro("cfg", parametros); // Toma configuración
3157
3158        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3159                db.GetErrorErrStr(ErrStr);
3160                return (false);
3161        }
3162        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3163                return (false); // Error al registrar notificación
3164        }
3165        if (strcmp(res, ACCION_FALLIDA) != 0) { // Ha habido algn error en la ejecución de la acción del cliente rembo
3166                if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph)) // El ordenador ha cambiado de configuración
3167                        return (false);
3168        }
3169        db.Close();
3170        return (true);
3171}
3172// ________________________________________________________________________________________________________
3173// Función: RESPUESTA_TomaHardware
3174//
3175//              Descripción:
3176//                      Esta función responde a un comando de Toma HArdware. Además actualiza la base de datos.
3177//              Parámetros:
3178//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3179//                      - parametros: parametros del comando
3180// ________________________________________________________________________________________________________
3181int RESPUESTA_TomaHardware(SOCKET s, char *parametros) {
3182        char ErrStr[200];
3183        Database db;
3184        Table tbl;
3185        char nomfiledst[512];
3186        char *res, *der, *ids, *iph, *ido, *hrd, *ipr, *rep;
3187
3188        res = toma_parametro("res", parametros); // Toma resultado
3189        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3190        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3191        iph = toma_parametro("iph", parametros); // Toma ip
3192        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3193
3194        hrd = toma_parametro("hrd", parametros); // Toma nombre del archivo de inventario
3195        ipr = toma_parametro("ipr", parametros); // Dirección IP repositorio
3196        rep = toma_parametro("rep", parametros); // puerto comunicaciones
3197
3198        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3199                db.GetErrorErrStr(ErrStr);
3200                return (false);
3201        }
3202        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3203                return (false); // Error al registrar notificacion
3204        }
3205        if (strcmp(res, ACCION_FALLIDA) != 0) {
3206                sprintf(nomfiledst, "/tmp/hard-%s", iph); // Nombre del fichero destino
3207                if (recibeFichero(ipr, rep, hrd, nomfiledst)) {
3208                        if (!actualiza_hardware(db, tbl, nomfiledst, iph, ido))
3209                                return (false);
3210                } else
3211                        return (false);
3212        }
3213        db.Close();
3214        return (true);
3215}
3216//______________________________________________________________________________________________________
3217// Función: recibeFichero
3218//
3219//      Descripción:
3220//              Se trae un fichero del repositorio y lo coloca en el diretorio /tmp
3221//      Parámetros:
3222//              - nomfile : Nombre del fichero
3223//      Devuelve:
3224//              true si el proceso es correcto y false en caso contrario
3225//      Especificaciones:
3226//              En los parametros de la trama se copian el contenido del del archivo de comandos
3227// ________________________________________________________________________________________________________
3228int recibeFichero(char *ipr, char *rep, char *nomfilesrc, char *nomfiledst) {
3229        SOCKET udpsock;
3230        int blk, lsize;
3231        char *b, *l;
3232        FILE *f;
3233        int ret;
3234        struct sockaddr_in addrRepo;
3235        socklen_t iAddrSize = sizeof(addrRepo);
3236        TRAMA trama;
3237
3238        udpsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3239        if (udpsock == SOCKET_ERROR) {
3240                RegistraLog(
3241                                "*** No se ha podido crear socket para comunicación con el repositorio en módulo recibeFichero",
3242                                true);
3243                return (false);
3244        }
3245
3246        f = fopen(nomfiledst, "wb");
3247        if (!f) {
3248                RegistraLog("*** No se ha podido crear archivo", false);
3249                close(udpsock);
3250                return (false);
3251        }
3252
3253        sprintf(trama.parametros, "nfn=mandaFichero\rnfl=%s\r", nomfilesrc); // Nombre de la función a ejecutar en el  servidor de administración
3254        if (envia_comandos(udpsock, &trama, ipr, atoi(rep))) {
3255                b = &trama.arroba; // Puntero al comienzo de la trama para colocar el bloque leido
3256                l = b + sizeof(blk); // Puntero después del dato bloque para colocar los bytes leidos
3257                do {
3258                        ret = recvfrom(udpsock, (char *) &trama, LONGITUD_TRAMA, 0,
3259                                        (struct sockaddr *) &addrRepo, &iAddrSize);
3260                        if (ret) {
3261                                memcpy(&blk, b, sizeof(blk));
3262                                memcpy(&lsize, l, sizeof(lsize));
3263                                if (lsize > 0)
3264                                        lsize = fwrite(trama.parametros, 1, lsize, f); // Escribe contenido en el fichero
3265                                else {
3266                                        fclose(f);
3267                                        close(udpsock);
3268                                        return (true);
3269                                }
3270                        } else {
3271                                RegistraLog("*** Error de recepción de archivo", false);
3272                                break;
3273                        }
3274                        envia_comandos(udpsock, &trama, ipr, atoi(rep));
3275                } while (lsize > 0);
3276                fclose(f);
3277        } else {
3278                RegistraLog(
3279                                "*** Error de envío de trama al repositorio en módulo recibeFichero",
3280                                false);
3281                close(udpsock);
3282                fclose(f);
3283                return (false);
3284        }
3285        close(udpsock);
3286        return (true);
3287}
3288// ________________________________________________________________________________________________________
3289// Función: RESPUESTA_TomaSoftware
3290//
3291//              Descripción:
3292//                      Esta función responde a un comando de Inventario Software. Además actualiza la base de datos.
3293//              Parámetros:
3294//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3295//                      - parametros: parámetros del comando
3296// ________________________________________________________________________________________________________
3297int RESPUESTA_TomaSoftware(SOCKET s, char *parametros) {
3298        char ErrStr[200];
3299        Database db;
3300        Table tbl;
3301        char nomfiledst[512];
3302        char *res, *der, *ids, *iph, *ido, *sft, *par, *tfs, *ipr, *rep;
3303
3304        res = toma_parametro("res", parametros); // Toma resultado
3305        der = toma_parametro("der", parametros); // Toma descripción del error ( si hubiera habido)
3306        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3307        iph = toma_parametro("iph", parametros); // Toma ip
3308        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3309
3310        sft = toma_parametro("sft", parametros); // Toma software
3311        par = toma_parametro("par", parametros); // Toma partición
3312        tfs = toma_parametro("tfs", parametros); // Toma tipo partición
3313
3314        ipr = toma_parametro("ipr", parametros); // Dirección IP repositorio
3315        rep = toma_parametro("rep", parametros); // puerto comunicaciones
3316
3317        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3318                db.GetErrorErrStr(ErrStr);
3319                return (false);
3320        }
3321        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3322                return (false); // Error al registrar notificación
3323        }
3324        if (strcmp(res, ACCION_FALLIDA) != 0) { // Ha habido algn error en la ejecución de la acción del cliente rembo
3325                sprintf(nomfiledst, "/tmp/soft-%s-%s", iph, par); // Nombre del fichero destino
3326                if (recibeFichero(ipr, rep, sft, nomfiledst)) {
3327                        if (!actualiza_software(db, tbl, nomfiledst, par, tfs, iph, ido)) // El ordenador ha cambiado de configuración
3328                                return (false);
3329                }
3330        } else
3331                return (false);
3332
3333        db.Close();
3334        return (true);
3335}
3336// ________________________________________________________________________________________________________
3337// Función: busca_comandos
3338//
3339//              Descripción:
3340//                      Esta función busca en la base de datos,comandos pendientes de ejecutar  para el ordenador cocreto
3341//              Parámetros:
3342//                      - iph: Dirección IP del ordenador
3343//                      - ido: Identificador del ordenador
3344//                      - parametros: parametros de la acción buscada
3345//                      - ids: Identificador de la acción
3346// ________________________________________________________________________________________________________
3347int busca_comandos(char* iph, char *ido, char *parametros, int *ids) {
3348        char sqlstr[1000], ErrStr[200];
3349        Database db;
3350        Table tbl, tbln;
3351
3352        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
3353                db.GetErrorErrStr(ErrStr);
3354                return (false);
3355        }
3356        sprintf(
3357                        sqlstr,
3358                        "SELECT idaccion,resultado,estado,parametros FROM acciones WHERE tipoaccion=%d AND estado = '%s' AND (resultado='%s' OR resultado='%s') AND parametros LIKE '%c%s%c' ORDER BY idaccion",
3359                        EJECUCION_COMANDO, ACCION_INICIADA, ACCION_SINERRORES,
3360                        ACCION_CONERRORES, 37, iph, 37);
3361        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3362                db.GetErrorErrStr(ErrStr);
3363                return (false);
3364        }
3365        if (tbl.ISEOF()) {
3366                db.Close();
3367                return (false); // No hay comandos pendientes
3368        }
3369
3370        while (!tbl.ISEOF()) { // Busca entre todas las acciones de diversos ambitos
3371
3372                if (!tbl.Get("parametros", parametros)) { // Toma parámetros
3373                        tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo parametros
3374                        return (false);
3375                }
3376
3377                if (IgualIP(parametros, iph)) { // Si existe la IP en la cadena
3378                        if (!tbl.Get("idaccion", *ids)) { // Toma identificador de la acción
3379                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3380                                return (false);
3381                        }
3382
3383                        // Comprueba que aunque el resultado es ACCION_INICIADA, este ordenador aún no ha notificado
3384                        sprintf(
3385                                        sqlstr,
3386                                        "SELECT idnotificador FROM notificaciones WHERE accionid=%d AND idnotificador=%s",
3387                                        *ids, ido);
3388                        if (!db.Execute(sqlstr, tbln)) { // Error al leer
3389                                db.GetErrorErrStr(ErrStr);
3390                                return (false);
3391                        }
3392                        if (tbln.ISEOF()) {
3393                                db.Close();
3394                                return (true); // No ha notificado este ordenador
3395                        }
3396                }
3397                tbl.MoveNext();
3398        }
3399        db.Close();
3400        return (false); // No hay mn acciones
3401}
3402// ________________________________________________________________________________________________________
3403// Función: InsertaNotificaciones
3404//
3405//
3406//              Parámetros:
3407//                      - idaccion: Identificador en la base de datos de la acción
3408//                      - idnotificador: Identificador en la base de datos de la notificación
3409//                      - accionid: Identificador de la acción padre
3410//                      - resultado: Resultado de la acción
3411//                      - db: Objeto conexión con la base de datos
3412// ________________________________________________________________________________________________________
3413int InsertaNotificaciones(int idaccion, int idnotificador, int accionid,
3414                char *resultado, Database db) {
3415
3416        struct tm* st;
3417        char ErrStr[200], sqlstr[1000];
3418        char fechahorareg[100];
3419        char descrinotificacion[100];
3420
3421        st = TomaHora();
3422        sprintf(fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3423                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3424
3425        strcpy(descrinotificacion, " ");
3426
3427        if (strcmp(resultado, ACCION_CONERRORES) == 0) {
3428                strcpy(descrinotificacion,
3429                                "Ha ocurrido algn error en la ejecución de esta tarea.");
3430                strcpy(resultado, ACCION_FALLIDA);
3431        }
3432        if (strcmp(resultado, ACCION_SINERRORES) == 0)
3433                strcpy(resultado, ACCION_EXITOSA);
3434
3435        sprintf(
3436                        sqlstr,
3437                        "INSERT INTO notificaciones (accionid,idnotificador,fechahorareg,resultado,descrinotificacion,idaccion) VALUES (%d,%d,'%s','%s','%s',%d)",
3438                        accionid, idnotificador, fechahorareg, resultado,
3439                        descrinotificacion, idaccion);
3440        if (!db.Execute(sqlstr)) { // Error al insertar
3441                db.GetErrorErrStr(ErrStr);
3442                return (false);
3443        }
3444        return (true);
3445}
3446// ________________________________________________________________________________________________________
3447// Función: comprueba_resultados
3448//
3449//
3450//              Parámetros:
3451//                      - idaccion: Identificador en la base de datos de la acción
3452//                      - db: Objeto de la base de datos
3453//
3454// ________________________________________________________________________________________________________
3455int comprueba_resultados(int idaccion, Database db) {
3456
3457        char ErrStr[200], sqlstr[1000];
3458        int numfallidas;
3459        char finalaccion[2];
3460        Table tbl;
3461
3462        sprintf(
3463                        sqlstr,
3464                        "SELECT COUNT(*) as numfallidas FROM notificaciones WHERE resultado='%s' AND accionid=%d",
3465                        ACCION_FALLIDA, idaccion);
3466        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3467                db.GetErrorErrStr(ErrStr);
3468                return (false);
3469        }
3470        if (tbl.ISEOF())
3471                return (false); // No existe registro de acciones
3472
3473        if (!tbl.Get("numfallidas", numfallidas)) { // Toma dato
3474                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3475                return (false);
3476        }
3477
3478        if (numfallidas > 0)
3479                strcpy(finalaccion, ACCION_CONERRORES);
3480        else
3481                strcpy(finalaccion, ACCION_SINERRORES);
3482
3483        sprintf(sqlstr, "UPDATE acciones SET resultado='%s' WHERE idaccion=%d",
3484                        finalaccion, idaccion);
3485        if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
3486                db.GetErrorErrStr(ErrStr);
3487                return (false);
3488        }
3489        // Comprueba si ha finalizado esta acción e inserta su notificador correspondiente
3490        return (comprueba_finalizada(idaccion, finalaccion, db));
3491}
3492// ________________________________________________________________________________________________________
3493// Función: comprueba_finalizada
3494//
3495//
3496//              Parámetros:
3497//                      - idaccion: Identificar en la base de datos de la acción
3498//                      - resultado: Resultado de la acción
3499//                      - db: Objeto conxión con la base de datos
3500// ________________________________________________________________________________________________________
3501int comprueba_finalizada(int idaccion, char *resultado, Database db) {
3502
3503        char ErrStr[200], sqlstr[1000];
3504        int numnotificaciones, tipoaccion, idnotificador;
3505        char parametros[LONGITUD_PARAMETROS], *cadenanot;
3506        char fechareg[100];
3507        int accionid, cont, i, resul, lon;
3508        Table tbl;
3509        struct tm* st;
3510
3511        sprintf(
3512                        sqlstr,
3513                        "SELECT COUNT(*) as numnotificaciones FROM notificaciones WHERE accionid=%d",
3514                        idaccion);
3515        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3516                db.GetErrorErrStr(ErrStr);
3517                return (false);
3518        }
3519        if (tbl.ISEOF())
3520                return (false); // No existe registro de acciones
3521
3522        if (!tbl.Get("numnotificaciones", numnotificaciones)) { // Toma dato
3523                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3524                return (false);
3525        }
3526
3527        sprintf(
3528                        sqlstr,
3529                        "SELECT tipoaccion,parametros,idnotificador,accionid FROM acciones WHERE idaccion=%d",
3530                        idaccion);
3531        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3532                db.GetErrorErrStr(ErrStr);
3533                return (false);
3534        }
3535        if (tbl.ISEOF())
3536                return (true); // No existe registro de acciones
3537
3538        if (!tbl.Get("tipoaccion", tipoaccion)) { // Toma dato
3539                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3540                return (false);
3541        }
3542        if (!tbl.Get("parametros", parametros)) { // Toma dato
3543                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3544                return (false);
3545        }
3546        if (!tbl.Get("idnotificador", idnotificador)) { // Toma dato
3547                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3548                return (false);
3549        }
3550        if (!tbl.Get("accionid", accionid)) { // Toma dato
3551                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3552                return (false);
3553        }
3554
3555        INTROaFINCAD(parametros);
3556        switch (tipoaccion) {
3557        case EJECUCION_COMANDO:
3558                cadenanot = toma_parametro("iph", parametros); // Toma cadenaip
3559                break;
3560        case EJECUCION_TAREA:
3561                cadenanot = toma_parametro("cmd", parametros); // Toma comandos
3562                break;
3563        case EJECUCION_TRABAJO:
3564                cadenanot = toma_parametro("tsk", parametros); // Toma tareas
3565                break;
3566        default:
3567                return (false);
3568        }
3569        cont = 1;
3570        lon = strlen(cadenanot);
3571        for (i = 0; i < lon; i++) {
3572                if (cadenanot[i] == ';')
3573                        cont++;
3574        }
3575        resul = true;
3576        if (numnotificaciones == cont) {
3577                st = TomaHora();
3578                sprintf(fechareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3579                                + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3580
3581                if (strcmp(resultado, ACCION_CONERRORES) == 0)
3582                        sprintf(
3583                                        sqlstr,
3584                                        "UPDATE acciones SET resultado='%s',estado='%s',fechahorafin='%s' WHERE idaccion=%d",
3585                                        ACCION_FALLIDA, ACCION_FINALIZADA, fechareg, idaccion);
3586                else
3587                        sprintf(
3588                                        sqlstr,
3589                                        "UPDATE acciones SET resultado='%s',estado='%s',fechahorafin='%s' WHERE idaccion=%d",
3590                                        ACCION_EXITOSA, ACCION_FINALIZADA, fechareg, idaccion);
3591
3592                if (!db.Execute(sqlstr)) { // Error al actualizar
3593                        db.GetErrorErrStr(ErrStr);
3594                        return (false);
3595                }
3596
3597                if (accionid > 0) { // Esto no se ejecutar si la tarea tiene un trabajo padre
3598                        resul = InsertaNotificaciones(idaccion, idnotificador, accionid,
3599                                        resultado, db);
3600                        if (resul)
3601                                return (comprueba_resultados(accionid, db));
3602                }
3603        }
3604        return (resul);
3605}
3606// ________________________________________________________________________________________________________
3607// Función: EnviaServidoresRembo
3608//
3609//              Descripción:
3610//                      Esta función envía una  trama a un servidor rembo para que sus clientes ejecuten un comando
3611//              Parámetros:
3612//                      - parametros: parametros del comando
3613//                      - cont: contador de clientes
3614// ________________________________________________________________________________________________________
3615void EnviaServidoresRembo(char * parametros, int cont) {
3616        int i, lon;
3617        char paux[20];
3618
3619        sprintf(paux, "ide=%d\r", TomaEnvio());
3620        strcat(parametros, paux); // Identificador de la sesión multicast
3621
3622        sprintf(paux, "nip=%d\r", cont);
3623        strcat(parametros, paux); // Contador de clientes a los que se envía la trama
3624
3625        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3626                if (tbsocketsSRVRMB[i].swenv == 1) { // El switch de envío está a uno, hay que enviar al servidor trama ...
3627                        strcat(parametros, "iph=");
3628                        strcat(parametros, tbsocketsSRVRMB[i].ipes);
3629                        lon = strlen(parametros);
3630                        parametros[lon - 1] = '\r'; // Quita la coma final
3631                        manda_trama_servidorrembo(tbsocketsSRVRMB[i].ip, parametros,
3632                                        tbsocketsSRVRMB[i].puertorepo);
3633                }
3634        }
3635}
3636// ________________________________________________________________________________________________________
3637// Función: manda_trama_servidorrembo
3638//
3639//              Descripción:
3640//                      Esta función envía  una  trama a un servidor rembo para que sus clientes ejecuten un comando
3641//              Parámetros:
3642//                      - ip_srvrbm: Dirección IP del servidor REMBO
3643//                      - parametros: parametros del comando
3644//                      - puertorepo: puerto del repositorio
3645// ________________________________________________________________________________________________________
3646int manda_trama_servidorrembo(char* ip_srvrbm, char *parametros, int puertorepo) {
3647        int ret;
3648        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
3649        if (!trama)
3650                return (false);
3651        strcpy(trama->parametros, parametros);
3652        SOCKET udpsock;
3653        udpsock = UDPConnect(IPlocal);
3654        if (udpsock == INVALID_SOCKET)
3655                return (false);
3656        ret = envia_comandos(udpsock, trama, ip_srvrbm, puertorepo);
3657        close(udpsock);
3658        return (ret);
3659}
3660//_______________________________________________________________________________________________________________
3661// Función: UDPConnect
3662//
3663//              Descripción:
3664//                      Crea un socket en un puerto determinado para la conversación UDP con el repositorio
3665//              Parámetros:
3666//                      - ips: Ip local
3667//_______________________________________________________________________________________________________________
3668SOCKET UDPConnect(char *ips) {
3669        SOCKET socket_c; // Socket para hebras (UDP)
3670        struct sockaddr_in cliente;
3671        int puerto;
3672
3673        socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP
3674
3675        if (socket_c == SOCKET_ERROR)
3676                return (INVALID_SOCKET);
3677
3678        cliente.sin_addr.s_addr = inet_addr(ips); // selecciona interface
3679        cliente.sin_family = AF_INET;
3680        puerto = PUERTOMINUSER;
3681        while (puerto < PUERTOMAXUSER) { // Busca puerto libre
3682                cliente.sin_port = htons(puerto); // Puerto asignado
3683                if (bind(socket_c, (struct sockaddr *) &cliente, sizeof(cliente))
3684                                == SOCKET_ERROR)
3685                        puerto++;
3686                else
3687                        break;
3688        }
3689        if (puerto >= PUERTOMAXUSER) { // No hay puertos libres
3690                return (INVALID_SOCKET);
3691        }
3692        return (socket_c);
3693}
3694//________________________________________________________________________________________________________
3695// Función: envia_comandos
3696//
3697//              Descripción:
3698//                      Enva trama UDP
3699//              Parámetros:
3700//                      - s: socket
3701//                      - trama: El contenido de la trama
3702//                      - ipsrv: Ip del repositorio
3703//                      - puerto: puerto de conexión
3704// ________________________________________________________________________________________________________
3705int envia_comandos(SOCKET s, TRAMA* trama, char* ipsrv, int puerto) {
3706        int ret, lon;
3707        struct sockaddr_in addrRepo;
3708
3709        trama->arroba = '@'; // cabecera de la trama
3710        strcpy(trama->identificador, "JMMLCAMDJ"); // identificador de la trama
3711        trama->ejecutor = '1'; // ejecutor de la trama 1=el servidor hidra  2=el cliente hidra
3712
3713        addrRepo.sin_family = AF_INET;
3714        addrRepo.sin_port = htons((short) puerto);
3715        addrRepo.sin_addr.s_addr = inet_addr(ipsrv); //  Dirección IP repositorio
3716        Encriptar((char*) trama);
3717        lon = strlen((char*) trama);
3718        ret = sendto(s, (char *) trama, lon, 0, (struct sockaddr *) &addrRepo,
3719                        sizeof(addrRepo));
3720        if (ret == SOCKET_ERROR) {
3721                RegistraLog("***send() fallo en envío al repositorio", true);
3722                return (FALSE);
3723        }
3724        return true;
3725}
3726// ________________________________________________________________________________________________________
3727// Función: DesmarcaServidoresRembo
3728//
3729//       Descripción:
3730//               Esta función desmarca la tabla completa de servidores rembo para iniciar la cuestion de envío
3731//       Parámetros:
3732//               Ninguno
3733// ________________________________________________________________________________________________________
3734void DesmarcaServidoresRembo(void) {
3735        int i;
3736        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3737                tbsocketsSRVRMB[i].swenv = 0;
3738                tbsocketsSRVRMB[i].ipes[0] = (char) NULL;
3739        }
3740}
3741// ________________________________________________________________________________________________________
3742// Función: MarcaServidoresRembo
3743//
3744//              Descripción:
3745//                      Esta función marca la tabla de servidores Rembo y coloca la ip del cliente en el buffer
3746//              Parámetros:
3747//                      - ipsrvrmb: ip del servidor rembo
3748//                      - ipclrmb: ip del cliente rembo
3749// ________________________________________________________________________________________________________
3750void MarcaServidoresRembo(char* ipsrvrmb, char*ipclrmb) {
3751        int i, resul;
3752        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3753                resul = strcmp(tbsocketsSRVRMB[i].ip, ipsrvrmb);
3754                if (resul == 0) {// servidor rembo encontrado
3755                        strcat(tbsocketsSRVRMB[i].ipes, ipclrmb);
3756                        strcat(tbsocketsSRVRMB[i].ipes, ";");
3757                        tbsocketsSRVRMB[i].swenv = 1;
3758                        return;
3759                }
3760        }
3761}
3762// ________________________________________________________________________________________________________
3763// Función: TomaIPServidorRembo
3764//
3765//              Descripción:
3766//                      Esta función devuelve true o false dependiendo si el Servidor REMBO está en la tabla  de servidores.
3767//              Parámetros:
3768//                      - ip : La ip del servidor a buscar
3769//                      - p: parámetro de salida. Si encuentra la ip trae el puerto en la variable
3770// ________________________________________________________________________________________________________
3771BOOLEAN TomaIPServidorRembo(char *ip, int *p) {
3772        int i, j;
3773        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
3774                if (strcmp(ip, tbsockets[i].ip) == 0) { // Si existe la IP ...
3775                        strcpy(ip, tbsockets[i].ipsrvrmb);
3776                        for (j = 0; j < MAXIMOS_SRVRMB; j++) {
3777                                if (strcmp(ip, tbsocketsSRVRMB[j].ip) == 0) { // Si existe la IP ...
3778                                        *p = tbsocketsSRVRMB[j].puertorepo;
3779                                        return (TRUE);
3780                                }
3781                        }
3782                }
3783        }
3784        return (FALSE);
3785}
3786
3787// ________________________________________________________________________________________________________
3788// Función: EjecutarTarea
3789//
3790//              Descripción:
3791//                      Registra una acción (Tarea) y la envía  para su ejecución
3792//              Parámetros:
3793//                      - idtarea : Identificador de la tarea
3794//                      - accionid: identificador del trabajo padre (si existe)
3795//                      - idnotificador:  identificador del trabajo_tarea incluido en el trabajo padre (si existe)
3796//                      - idcentro: Centro propietario del trabjo padre (si existe este trabajo)
3797//                      - db: Objeto de la base de datos
3798//                      - parametros: parámetros de la acción
3799// ________________________________________________________________________________________________________
3800int EjecutarTarea(int idtarea, int accionid, int idnotificador, int idcentro,
3801                Database db, char* parametros) {
3802        char sqlstr[1000], ErrStr[200], ambito;
3803        Table tbl;
3804        int cont_comandos = 0, lon;
3805        int idcomando, idambito, idtareacomando, accionidcmd;
3806        char wambitarea[20], ambitarea[4000];
3807        char wparamtarea[20], paramtarea[1000], pids[20];
3808        int tblon[100], tbComandosidcomando[100], tbComandosambito[100],
3809                        tbComandosidnotificador[100], tbComandosidambito[100];
3810        char *tbComandosparametros[100];
3811
3812        ambitarea[0] = (char) NULL; // Inicialización
3813        strcpy(paramtarea, "cmd="); // Inicialización
3814        if (idcentro == 0) {
3815                // recupera el identificador del Centro propietario de la tarea
3816                sprintf(sqlstr, "SELECT idcentro FROM tareas WHERE idtarea=%d", idtarea);
3817                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3818                        db.GetErrorErrStr(ErrStr);
3819                        return (false);
3820                }
3821                if (tbl.ISEOF())
3822                        return (true);
3823                if (!tbl.Get("idcentro", idcentro)) { // Toma dato
3824                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3825                        return (false);
3826                }
3827        }
3828        // Recupera los comandos que forman parte de la tarea
3829        sprintf(sqlstr,
3830                        "SELECT * FROM tareas_comandos WHERE idtarea=%d ORDER by orden",
3831                        idtarea);
3832        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3833                db.GetErrorErrStr(ErrStr);
3834                return (false);
3835        }
3836        if (tbl.ISEOF())
3837                return (true);
3838
3839        // Recorre tareas-comandos
3840        while (!tbl.ISEOF()) {
3841                if (!tbl.Get("idcomando", idcomando)) { // Toma dato
3842                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3843                        return (false);
3844                }
3845                tbComandosidcomando[cont_comandos] = idcomando;
3846
3847                if (!tbl.Get("ambito", ambito)) { // Toma dato
3848                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3849                        return (false);
3850                }
3851                tbComandosambito[cont_comandos] = ambito;
3852
3853                if (!tbl.Get("idambito", idambito)) { // Toma dato
3854                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3855                        return (false);
3856                }
3857                tbComandosidambito[cont_comandos] = idambito;
3858
3859                if (!tbl.Get("parametros", parametros)) { // Toma dato
3860                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3861                        return (false);
3862                }
3863
3864                lon = strlen(parametros);
3865                tblon[cont_comandos] = lon;
3866                tbComandosparametros[cont_comandos] = (char*) malloc(lon + 20);
3867                if (tbComandosparametros[cont_comandos] == NULL)
3868                        return (false); // No hay memoria suficiente
3869
3870                strcpy(tbComandosparametros[cont_comandos], parametros);
3871
3872                if (!tbl.Get("idtareacomando", idtareacomando)) { // Toma dato
3873                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3874                        return (false);
3875                }
3876                tbComandosidnotificador[cont_comandos] = idtareacomando;
3877
3878                sprintf(wambitarea, "%d:%d;", ambito, idambito);
3879                strcat(ambitarea, wambitarea);
3880
3881                sprintf(wparamtarea, "%d;", idtareacomando);
3882                strcat(paramtarea, wparamtarea);
3883
3884                cont_comandos++;
3885                tbl.MoveNext();
3886        }
3887        lon = strlen(ambitarea);
3888        ambitarea[lon - 1] = (char) NULL; // Quita la coma final
3889
3890        lon = strlen(paramtarea);
3891        paramtarea[lon - 1] = (char) NULL; // Quita la coma final
3892
3893        char _fechahorareg[100];
3894        struct tm* st;
3895        st = TomaHora();
3896        sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3897                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3898
3899        sprintf(
3900                        sqlstr,
3901                        "INSERT INTO acciones (tipoaccion,idtipoaccion,cateaccion,ambito,idambito,ambitskwrk,fechahorareg,estado,resultado,idcentro,parametros,accionid,idnotificador) VALUES (%d,%d,%d,0,0,'%s','%s','%s','%s',%d,'%s',%d,%d)",
3902                        EJECUCION_TAREA, idtarea, PROCESOS, ambitarea, _fechahorareg,
3903                        ACCION_INICIADA, ACCION_SINERRORES, idcentro, paramtarea, accionid,
3904                        idnotificador);
3905        if (!db.Execute(sqlstr)) { // Error al insertar
3906                db.GetErrorErrStr(ErrStr);
3907                return (false);
3908        }
3909        accionid = 0;
3910        // Toma identificador dela acción
3911        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3912        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3913                db.GetErrorErrStr(ErrStr);
3914                return (false);
3915        }
3916        if (!tbl.ISEOF()) { // Si existe registro
3917                if (!tbl.Get("identificador", accionid)) {
3918                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3919                        return (false);
3920                }
3921        }
3922        int i;
3923        // Insertar acciones:comandos
3924        for (i = 0; i < cont_comandos; i++) {
3925                st = TomaHora();
3926                sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900,
3927                                st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min,
3928                                st->tm_sec);
3929                sprintf(
3930                                sqlstr,
3931                                "INSERT INTO acciones (tipoaccion,idtipoaccion,cateaccion,ambito,idambito,fechahorareg,estado,resultado,idcentro,parametros,accionid,idnotificador) VALUES (%d,%d,%d,%d,%d,'%s','%s','%s',%d,'%s',%d,%d)",
3932                                EJECUCION_COMANDO, tbComandosidcomando[i], PROCESOS,
3933                                tbComandosambito[i], tbComandosidambito[i], _fechahorareg,
3934                                ACCION_EXITOSA, ACCION_SINERRORES, idcentro,
3935                                tbComandosparametros[i], accionid, tbComandosidnotificador[i]);
3936                if (!db.Execute(sqlstr)) { // Error al insertar
3937                        db.GetErrorErrStr(ErrStr);
3938                        free(tbComandosparametros[i]);
3939                        return (false);
3940                }
3941                // Toma identificador dela acción
3942                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3943                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3944                        db.GetErrorErrStr(ErrStr);
3945                        return (false);
3946                }
3947                if (!tbl.ISEOF()) { // Si existe registro
3948                        if (!tbl.Get("identificador", accionidcmd)) {
3949                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3950                                return (false);
3951                        }
3952                }
3953                sprintf(pids, "ids=%d\r", accionidcmd);
3954                strcat((char*) tbComandosparametros[i], pids); // Le ande el identificador de la acción
3955                envia_tarea(tbComandosparametros[i]);
3956                free(tbComandosparametros[i]);
3957        }
3958        return (true);
3959}
3960// ________________________________________________________________________________________________________
3961// Función: envia_tarea
3962//
3963//              Descripción:
3964//                      Esta función envía  una tarea  por la red.
3965//              Parámetros:
3966//                      - parametros: El contenido de la tarea
3967// ________________________________________________________________________________________________________
3968void envia_tarea(char* parametros) {
3969        TRAMA trama;
3970
3971        trama.arroba = '@';
3972        strncpy(trama.identificador, "JMMLCAMDJ", 9);
3973        trama.ejecutor = parametros[0];
3974        strcpy(trama.parametros, (char*) &parametros[1]);
3975        gestiona_comando(INVALID_SOCKET, trama);
3976}
3977// ________________________________________________________________________________________________________
3978// Función: EjecutarTrabajo
3979//
3980//              Descripción:
3981//                      Registra una acción (Trabajo) y la envía  para su ejecución
3982//              Parámetros:
3983//                      - idtrabajo : Identificador del trabajo
3984//                      - db: Objeto de la base de datos
3985//                      - parametros: parámetros de la acción
3986// ________________________________________________________________________________________________________
3987int EjecutarTrabajo(int idtrabajo, Database db, char*parametros) {
3988        char sqlstr[1000], ErrStr[200];
3989        Table tbl;
3990        int cont_tareas = 0, lon;
3991        int idtarea, idtrabajotarea, idcentro;
3992        char wambitrabajo[500], ambitrabajo[4000];
3993        char wparamtrabajo[20], paramtrabajo[1000];
3994        int tbTareasidtarea[100], tbTareasidnotificador[100];
3995        char ambitskwrk[500];
3996
3997        ambitrabajo[0] = (char) NULL; // Inicialización
3998        strcpy(paramtrabajo, "tsk="); // Inicialización
3999
4000        // recupera el identificador del Centro propietario de la tarea
4001        sprintf(sqlstr, "SELECT idcentro FROM trabajos WHERE idtrabajo=%d",
4002                        idtrabajo);
4003        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4004                db.GetErrorErrStr(ErrStr);
4005                return (false);
4006        }
4007        if (tbl.ISEOF())
4008                return (true);
4009        if (!tbl.Get("idcentro", idcentro)) { // Toma dato
4010                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4011                return (false);
4012        }
4013        // Recupera las tareas que forman parte del trabajo
4014        sprintf(sqlstr,
4015                        "SELECT * FROM trabajos_tareas WHERE idtrabajo=%d ORDER by orden",
4016                        idtrabajo);
4017        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4018                db.GetErrorErrStr(ErrStr);
4019                return (false);
4020        }
4021        if (tbl.ISEOF())
4022                return (true);
4023        // Recorre trabajos-tareas
4024        while (!tbl.ISEOF()) {
4025                if (!tbl.Get("idtrabajotarea", idtrabajotarea)) { // Toma dato
4026                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4027                        return (false);
4028                }
4029                tbTareasidnotificador[cont_tareas] = idtrabajotarea;
4030
4031                if (!tbl.Get("idtarea", idtarea)) { // Toma dato
4032                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4033                        return (false);
4034                }
4035                tbTareasidtarea[cont_tareas] = idtarea;
4036
4037                if (!tbl.Get("parametros", parametros)) { // Toma dato
4038                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4039                        return (false);
4040                }
4041
4042                if (!tbl.Get("ambitskwrk", ambitskwrk)) { // Toma dato
4043                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4044                        return (false);
4045                }
4046                sprintf(wambitrabajo, "%s;", ambitskwrk);
4047                strcat(ambitrabajo, wambitrabajo);
4048
4049                sprintf(wparamtrabajo, "%d;", idtrabajotarea);
4050                strcat(paramtrabajo, wparamtrabajo);
4051
4052                cont_tareas++;
4053                tbl.MoveNext();
4054        }
4055        lon = strlen(ambitrabajo);
4056        ambitrabajo[lon - 1] = (char) NULL; // Quita la coma final
4057
4058        lon = strlen(paramtrabajo);
4059        paramtrabajo[lon - 1] = (char) NULL; // Quita la coma final
4060
4061        char _fechahorareg[100];
4062        struct tm* st;
4063        st = TomaHora();
4064        sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
4065                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
4066
4067        sprintf(
4068                        sqlstr,
4069                        "INSERT INTO acciones (tipoaccion,idtipoaccion,cateaccion,ambito,idambito,ambitskwrk,fechahorareg,estado,resultado,idcentro,parametros,accionid,idnotificador) VALUES (%d,%d,%d,0,0,'%s','%s','%s','%s',%d,'%s',0,0)",
4070                        EJECUCION_TRABAJO, idtrabajo, PROCESOS, ambitrabajo, _fechahorareg,
4071                        ACCION_INICIADA, ACCION_SINERRORES, idcentro, paramtrabajo);
4072        if (!db.Execute(sqlstr)) { // Error al insertar
4073                db.GetErrorErrStr(ErrStr);
4074                return (false);
4075        }
4076        int accionid = 0;
4077        // Toma identificador dela acción
4078        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
4079        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4080                db.GetErrorErrStr(ErrStr);
4081                return (false);
4082        }
4083        if (!tbl.ISEOF()) { // Si existe registro
4084                if (!tbl.Get("identificador", accionid)) {
4085                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4086                        return (false);
4087                }
4088        }
4089        int i;
4090        // Insertar acciones:tareas
4091        for (i = 0; i < cont_tareas; i++) {
4092                if (!EjecutarTarea(tbTareasidtarea[i], accionid,
4093                                tbTareasidnotificador[i], idcentro, db, parametros)) {
4094                        return (false);
4095                }
4096        }
4097        return (true);
4098}
4099// ________________________________________________________________________________________________________
4100// Función: cuestion_nuevoordenador
4101//
4102//              Descripción:
4103//                      Esta función da de alta un ordenador y un aula si el sistema está configurado para ello
4104//              Parámetros:
4105//                      - db: Objeto base de datos (ya operativo)
4106//                      - tbl: Objeto tabla
4107//                      - ido: identificador del ordenador que se dará de alta automáticamente (se devuelve)
4108//                      - nau: Nombre del grupo donde estnel ordenador( rembo.conf)
4109//                      - nor: Nombre del ordenador dado por rembo(dhcpd)
4110//                      - iph: IP del ordenador
4111//                      - mac: MAC del ordenador
4112//                      - cfg: configuración
4113//                      - ipd: ip del servidor dhcp
4114//                      - ipr: ip del servidor rembo
4115// ________________________________________________________________________________________________________
4116int cuestion_nuevoordenador(Database db, Table tbl, int*ido, char *nau,
4117                char *nor, char *iph, char *mac, char*cfg, char*ipd, char*ipr) {
4118        char sqlstr[1000], ErrStr[200];
4119        int ida, isd, isr;
4120
4121        // Recupera los datos del aula
4122        sprintf(sqlstr, "SELECT idaula FROM aulas  WHERE nombreaula= '%s'", nau);
4123
4124        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4125                db.GetErrorErrStr(ErrStr);
4126                return (false);
4127        }
4128        if (tbl.ISEOF()) { // Si NO existe el aula
4129                sprintf(sqlstr, "SELECT idaula FROM aulas  WHERE nombreaula= '%s'",
4130                                "Default");
4131                if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4132                        db.GetErrorErrStr(ErrStr);
4133                        return (false);
4134                }
4135                if (tbl.ISEOF()) { // Inserta el aula por defecto
4136                        sprintf(sqlstr, "INSERT INTO aulas (nombreaula) VALUES ('Default')");
4137                        if (!db.Execute(sqlstr)) { // Error al insertar
4138                                db.GetErrorErrStr(ErrStr);
4139                                return (false);
4140                        }
4141                        ida = 0;
4142                        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
4143                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4144                                db.GetErrorErrStr(ErrStr);
4145                                return (false);
4146                        }
4147                        if (!tbl.ISEOF()) { // Si existe registro
4148                                if (!tbl.Get("identificador", ida)) {
4149                                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4150                                        return (false);
4151                                }
4152                        }
4153                }
4154        } else {
4155                if (!tbl.Get("idaula", ida)) { // Toma dato
4156                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4157                        return (false);
4158                }
4159        }
4160        if (!Toma_idservidorres(db, tbl, ipd, ipr, &isd, &isr))
4161                return (false);
4162        if (!alta_ordenador(db, tbl, ido, nor, iph, mac, ida, isd, isr))
4163                return (false); // Alta del ordenador
4164        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph)) { // Actualiza la configuración del ordenador
4165                return (false);
4166        }
4167        return (true);
4168}
4169// ________________________________________________________________________________________________________
4170// Función: alta_ordenador
4171//
4172//              Descripción:
4173//                      Esta funcin da de alta un ordenador
4174//              Parámetros:
4175//                      - db: Objeto base de datos (ya operativo)
4176//                      - tbl: Objeto tabla
4177//                      - mac: MAC del ordenador
4178//                      - ida: Identificador del aula
4179//                      - isd: Identificador del servidor dhcp
4180//                      - isr: Identificador del servidor rembo
4181// ________________________________________________________________________________________________________
4182int alta_ordenador(Database db, Table tbl, int* ido, char *nor, char *iph,
4183                char*mac, int ida, int isd, int isr) {
4184        char sqlstr[1000], ErrStr[200], strmac[20];
4185        int idordenador, lon, i, p;
4186
4187        // Prepara mac
4188        lon = strlen(mac);
4189        p = 0;
4190        for (i = 0; i < lon; i++) {
4191                if (mac[i] != ' ') // Si no es espacio
4192                        strmac[p++] = mac[i];
4193        }
4194        strmac[p] = (char) NULL;
4195
4196        sprintf(
4197                        sqlstr,
4198                        "INSERT INTO ordenadores(nombreordenador,ip,mac,idperfilhard,idservidordhcp,idservidorrembo,idmenu,idaula,grupoid,idconfiguracion) VALUES ('%s','%s','%s',0,%d,%d,0,%d,0,0)",
4199                        nor, iph, strmac, isd, isr, ida);
4200        if (!db.Execute(sqlstr)) { // Error al insertar
4201                db.GetErrorErrStr(ErrStr);
4202                return (false);
4203        }
4204        idordenador = 0;
4205        // Toma identificador dela acción
4206        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
4207        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4208                db.GetErrorErrStr(ErrStr);
4209                return (false);
4210        }
4211        if (!tbl.ISEOF()) { // Si existe registro
4212                if (!tbl.Get("identificador", idordenador)) {
4213                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4214                        return (false);
4215                }
4216        }
4217        *ido = idordenador;
4218        return (true);
4219}
4220// ________________________________________________________________________________________________________
4221// Función: Toma_idservidorres
4222//
4223//              Descripción:
4224//                      Esta funcin devuelve los identificadores de los servidores rembo y dhcp de un determinado ordenador
4225//              Parámetros:
4226//                              db: Objeto base de datos (ya operativo)
4227//                              tbl: Objeto tabla
4228//                              ipd: ip del servidor dhcp
4229//                              ipr: ip del servidor rembo
4230//                              isd: identificador del servidor dhcp
4231//                              isr: identificador del servidor rembo
4232// ________________________________________________________________________________________________________
4233int Toma_idservidorres(Database db, Table tbl, char*ipd, char*ipr, int*isd,
4234                int*isr) {
4235        char sqlstr[1000], ErrStr[200];
4236        int identificador_dhcp = 0;
4237        int identificador_rembo, puertorepo_rembo;
4238
4239        /* Servidor dhcp
4240         sprintf(sqlstr,"SELECT idservidordhcp FROM servidoresdhcp where ip='%s'",ipd);
4241         if(!db.Execute(sqlstr,tbl)){ // Error al leer
4242         db.GetErrorErrStr(ErrStr);
4243         return(false);
4244         }
4245         if(!tbl.ISEOF()){ // Si existe registro
4246         if(!tbl.Get("idservidordhcp",identificador_dhcp)){
4247         tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4248         return(false);
4249         }
4250         }
4251         */
4252        // Servidor rembo
4253        sprintf(
4254                        sqlstr,
4255                        "SELECT idservidorrembo,puertorepo FROM servidoresrembo where ip='%s'",
4256                        ipr);
4257        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4258                db.GetErrorErrStr(ErrStr);
4259                return (false);
4260        }
4261        if (!tbl.ISEOF()) { // Si existe registro
4262                if (!tbl.Get("idservidorrembo", identificador_rembo)) {
4263                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4264                        return (false);
4265                }
4266                if (!tbl.Get("puertorepo", puertorepo_rembo)) {
4267                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4268                        return (false);
4269                }
4270        }
4271        *isd = identificador_dhcp;
4272        *isr = identificador_rembo;
4273
4274        return (true);
4275}
4276// ________________________________________________________________________________________________________
4277// Función: tomaIpRepoPort
4278//
4279//              Descripción:
4280//                      Devuelve la ip y el puerto de un repositorio
4281//              Parámetros:
4282//                              iph: ip del cliente
4283//                              ipr: ip del servidor rembo
4284//                              rep: puerto del repositorio
4285// ________________________________________________________________________________________________________
4286int tomaIpRepoPort(char *iph, char *ipr, char *rep) {
4287        char ErrStr[200], sqlstr[1000];
4288        Database db;
4289        Table tbl;
4290        char iprepositorio[16];
4291        int puertorepo;
4292
4293        // Toma las propiedades del ordenador
4294        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
4295                RegistraLog("Error de conexión con la base de datos", false);
4296                db.GetErrorErrStr(ErrStr);
4297                return (false);
4298        }
4299        // Recupera los datos del ordenador
4300        sprintf(
4301                        sqlstr,
4302                        "SELECT servidoresrembo.ip,servidoresrembo.puertorepo"
4303                                " FROM ordenadores "
4304                                " INNER JOIN  servidoresrembo ON ordenadores.idservidorrembo = servidoresrembo.idservidorrembo"
4305                                " WHERE ordenadores.ip = '%s'", iph);
4306
4307        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4308                RegistraLog("Error al ejecutar la consulta", false);
4309                db.GetErrorErrStr(ErrStr);
4310                return (false);
4311        }
4312        if (tbl.ISEOF()) { // Si No existe registro
4313                RegistraLog("Repositorio NO encontrado", false);
4314                return (false);
4315
4316        } else {
4317                if (!tbl.Get("ip", iprepositorio)) { // Toma dato
4318                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4319                        return (false);
4320                }
4321                if (!tbl.Get("puertorepo", puertorepo)) { // Toma dato
4322                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4323                        return (false);
4324                }
4325        }
4326        sprintf(ipr, "%s", iprepositorio);
4327        sprintf(rep, "%d", puertorepo);
4328        db.Close();
4329        return (true);
4330}
4331//************************************************************************************************************************************************
4332// PROGRAMA PRINCIPAL (SERVICIO)
4333//***************************************************************************************************************************************************
4334int main(int argc, char *argv[]) {
4335        SOCKET socket_s; // Socket donde escucha el servidor
4336        SOCKET socket_c; // Socket de los clientes que se conectan
4337        int i;// Tamaño de la estructura de direccionamiento IP del cliente
4338        socklen_t iAddrSize;
4339        struct sockaddr_in local, cliente;
4340        //pthread_t hThread;
4341        //void *resul
4342        // Validación de parámetros
4343
4344        strcpy(szPathFileCfg, "ogAdmServer.cfg");
4345        strcpy(szPathFileLog, "ogAdmServer.log");
4346
4347        for (i = 1; (i + 1) < argc; i += 2) {
4348                if (argv[i][0] == '-') {
4349                        switch (tolower(argv[i][1])) {
4350                        case 'f':
4351                                if (argv[i + 1] != NULL)
4352                                        strcpy(szPathFileCfg, argv[i + 1]);
4353                                else {
4354                                        RegistraLog(
4355                                                        "Fallo en los parámetros: Debe especificar el fichero de configuración del servicio",
4356                                                        false);
4357                                        exit(EXIT_FAILURE);
4358                                }
4359                                break;
4360                        case 'l':
4361                                if (argv[i + 1] != NULL)
4362                                        strcpy(szPathFileLog, argv[i + 1]);
4363                                else {
4364                                        RegistraLog(
4365                                                        "Fallo en los parámetros: Debe especificar el fichero de log para el servicio",
4366                                                        false);
4367                                        exit(EXIT_FAILURE);
4368                                }
4369                                break;
4370                        default:
4371                                RegistraLog(
4372                                                "Fallo de sintaxis en los parámetros: Debe especificar -f nombre_del_fichero_de_configuración_del_servicio",
4373                                                false);
4374                                exit(EXIT_FAILURE);
4375                                break;
4376                        }
4377                }
4378        }
4379        if (szPathFileCfg == NULL) {
4380                printf("***Error. No se ha especificado fichero de configuración\n");
4381                exit(EXIT_FAILURE);
4382        }
4383        if (!TomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuración
4384                RegistraLog(
4385                                "El fichero de configuración contiene un error de sintaxis",
4386                                false);
4387                exit(EXIT_FAILURE);
4388        }
4389        pthread_mutex_init(&guardia, NULL); // Creación del mutex para control de hebras
4390
4391        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
4392                tbsockets[i].ip[0] = '\0'; // Inicializa IP
4393                tbsockets[i].sock = INVALID_SOCKET; // Inicializa Socket
4394        }
4395        RegistraLog("***Inicio de sesion***", false);
4396
4397        socket_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Crea socket
4398        if (socket_s == SOCKET_ERROR) {
4399                RegistraLog("***socket() fallo:", true);
4400        }
4401        local.sin_addr.s_addr = htonl(INADDR_ANY); // selecciona interface
4402        local.sin_family = AF_INET;
4403        local.sin_port = htons(puerto); // Puerto
4404
4405        if (bind(socket_s, (struct sockaddr *) &local, // Enlaza socket
4406                        sizeof(local)) == SOCKET_ERROR) {
4407                RegistraLog("***bind() fallo:", true);
4408                exit(EXIT_FAILURE);
4409        }
4410
4411        listen(socket_s, 250); // Pone a escuchar al socket
4412        iAddrSize = sizeof(cliente);
4413
4414        while (true) { // Bucle para escuchar peticiones de clientes
4415                socket_c = accept(socket_s, (struct sockaddr *) &cliente, &iAddrSize);
4416                if (socket_c == INVALID_SOCKET) {
4417                        RegistraLog("***accept() fallo:", true);
4418                        break;
4419                }
4420                //resul=pthread_create(&hThread,NULL,GestionaConexion,(void*)&socket_c);
4421                GestionaConexion(&socket_c);
4422                /*if(resul!=0){2
4423                 RegistraLog("***Fallo al crear la hebra cliente",false);
4424                 break;
4425                 }
4426                 */
4427                //pthread_detach(hThread);
4428                close(socket_c); // Cierra la conexión con el servidor hidra
4429        }
4430        close(socket_s);
4431        exit(EXIT_SUCCESS);
4432}
Note: See TracBrowser for help on using the repository browser.