source: admin/Services/ogAdmServer/sources/ogAdmServer.cpp @ 74c04a0

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 74c04a0 was 74c04a0, checked in by alonso <alonso@…>, 15 years ago

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

  • Property mode set to 100644
File size: 153.9 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, *ifs,*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        ifs = toma_parametro("ifs", parametros); // Identificador del perfil software
2944        idi = toma_parametro("idi", parametros); // identificador de la imagen
2945
2946        strcpy(gido, ido); // Guarda el identificador del ordenador
2947
2948        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
2949                return (false); // Error al registrar notificacion
2950        }
2951        if (strcmp(res, ACCION_FALLIDA) == 0) { // Ha habido algn error en la ejecucin de la acción del cliente rembo
2952                db.Close();
2953                return (false);
2954        }
2955
2956        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
2957                return (false); // Erro al actualiza la configuracin
2958        if (!Actualiza_ordenador_imagen(par, idi, gido, db))
2959                return (false);
2960        if (Actualiza_ordenador_perfil(gido,par,ifs,db))
2961                return (false);
2962
2963        db.Close();
2964        return (true);
2965}
2966// ________________________________________________________________________________________________________
2967// Función: Actualiza_ordenador_imagen
2968//
2969//              Descripción:
2970//                      Esta función actualiza la tabla ordenador_imagen
2971//              Parámetros:
2972//                      - par: partición
2973//                      - idi: identificador de la imagen ( 0 ninguna )
2974//                      - ido: identificador del ordenador
2975//                      - db: Conexión ADO operativa
2976// ________________________________________________________________________________________________________
2977int Actualiza_ordenador_imagen(char *par, const char *idi, char *ido,Database db) {
2978        char ErrStr[200], sqlstr[1000];
2979        Table tbl;
2980        int idimagen, idimagenres;
2981
2982        idimagenres = atoi(idi);
2983        if (idimagenres == 0) { // Se ha formateado la partición y se ha borrado la imagen por tanto
2984                sprintf(
2985                                sqlstr,
2986                                "DELETE FROM ordenador_imagen WHERE idordenador=%s AND particion=%s",
2987                                ido, par);
2988                if (!db.Execute(sqlstr)) { // Error al insertar
2989                        db.GetErrorErrStr(ErrStr);
2990                        return (false);
2991                }
2992                return (true);
2993        }
2994
2995        sprintf(
2996                        sqlstr,
2997                        "SELECT idimagen FROM ordenador_imagen INNER JOIN ordenadores ON ordenador_imagen.idordenador = ordenadores.idordenador WHERE ordenadores.idordenador = %s AND ordenador_imagen.particion = %s",
2998                        ido, par);
2999        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3000                db.GetErrorErrStr(ErrStr);
3001                return (false);
3002        }
3003        if (!tbl.ISEOF()) { // Existe registro
3004                if (!tbl.Get("idimagen", idimagen)) {
3005                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3006                        return (false);
3007                } else {
3008                        if (idimagenres != idimagen) {
3009                                sprintf(
3010                                                sqlstr,
3011                                                "Update ordenador_imagen set idimagen=%s WHERE idordenador=%s AND particion=%s",
3012                                                idi, ido, par);
3013                                if (!db.Execute(sqlstr)) { // Error al actualizar
3014                                        db.GetErrorErrStr(ErrStr);
3015                                        return (false);
3016                                }
3017                        }
3018                }
3019        } else { // No existe el registro
3020                sprintf(
3021                                sqlstr,
3022                                "INSERT INTO ordenador_imagen (idordenador,particion,idimagen) VALUES(%s,%s,%s)",
3023                                ido, par, idi);
3024                if (!db.Execute(sqlstr)) { // Error al insertar
3025                        db.GetErrorErrStr(ErrStr);
3026                        return (false);
3027                }
3028        }
3029        return (true);
3030}
3031// ________________________________________________________________________________________________________
3032// Función: Actualiza_ordenador_perfil
3033//
3034//              Descripción:
3035//                      Esta función actualiza la tabla ordenador_perfilsof
3036//              Parámetros:
3037//                      - par: partición
3038//                      - ido: identificador de la imagen ( 0 ninguna )
3039//                      - ips: identificador del ordenador
3040//                      - db: Conexión ADO operativa
3041// ________________________________________________________________________________________________________
3042int Actualiza_ordenador_perfil(char *ido,char *par,char *ifs,Database db)
3043{
3044        char ErrStr[200], sqlstr[1000];
3045        Table tbl;
3046        int idperfilsoft;
3047
3048        sprintf(sqlstr,
3049                                "SELECT idperfilsoft FROM ordenador_perfilsoft"\
3050                                " WHERE idordenador = %s AND particion=%s",ido,par);
3051
3052        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3053                db.GetErrorErrStr(ErrStr);
3054                return (false);
3055        }
3056        if (!tbl.ISEOF()) { // Existe registro
3057                if (!tbl.Get("idperfilsoft", idperfilsoft)) {
3058                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3059                        return (false);
3060                }
3061                if (idperfilsoft != atoi(ifs)) {
3062                        sprintf(sqlstr, "Update ordenador_perfilsoft set idperfilsoft=%s WHERE idordenador=%s AND particion=%s",ifs, ido, par);
3063                        if (!db.Execute(sqlstr)) { // Error al actualizar
3064                                db.GetErrorErrStr(ErrStr);
3065                                return (false);
3066                        }
3067                }
3068        }
3069        else{ // No existe el registro
3070                sprintf(sqlstr, "INSERT INTO ordenador_perfilsoft (idordenador,particion,idperfilsoft) VALUES(%s,%s,%s)",ido, par, ifs);
3071                if (!db.Execute(sqlstr)) { // Error al insertar
3072                        db.GetErrorErrStr(ErrStr);
3073                        return (false);
3074                }
3075        }
3076        return (true);
3077}
3078// ________________________________________________________________________________________________________
3079// Función: RESPUESTA_ParticionaryFormatear
3080//
3081//              Descripción:
3082//                      Esta función responde a un comando de particionar y formatear.  Además actualiza la base de datos.
3083//              Parámetros:
3084//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3085//                      - parametros: parametros del comando
3086// ________________________________________________________________________________________________________
3087int RESPUESTA_ParticionaryFormatear(SOCKET s, char *parametros) {
3088        char sqlstr[1000], ErrStr[200], gido[20];
3089        Database db;
3090        Table tbl;
3091        char *res, *der, *ids, *iph, *ido, *cfg;
3092
3093        res = toma_parametro("res", parametros); // Toma resultado
3094        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3095        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3096        iph = toma_parametro("iph", parametros); // Toma ip
3097        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3098        cfg = toma_parametro("cfg", parametros); // Toma configuracin
3099
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        if (strcmp(res, ACCION_FALLIDA) == 0) {
3110                db.Close();
3111                return (true); // Ha habido algn error en la ejecucin de la acción del cliente rembo
3112        }
3113        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
3114                return (false); // Error al actualiza la configuración
3115
3116        // Elimina información sobre imagenes en este ordenador, al haber sido formateado
3117        sprintf(sqlstr, "DELETE FROM ordenador_imagen WHERE idordenador=%s", gido);
3118        if (!db.Execute(sqlstr)) { // Error al insertar
3119                db.GetErrorErrStr(ErrStr);
3120                return (false);
3121        }
3122        db.Close();
3123        return (true);
3124}
3125// ________________________________________________________________________________________________________
3126// Función: RESPUESTA_Configurar
3127//
3128//              Descripción:
3129//                      Esta función responde a un comando de Configurar. Además actualiza la base de datos.
3130//              Parámetros:
3131//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3132//                      - parametros: parámetros del comando
3133// ________________________________________________________________________________________________________
3134int RESPUESTA_Configurar(SOCKET s, char *parametros) {
3135        char ErrStr[200], gids[20], gido[20];
3136        Database db;
3137        Table tbl;
3138        int lon, resul, i;
3139        char *res, *der, *ids, *iph, *ido, *cfg, *hdc;
3140
3141        res = toma_parametro("res", parametros); // Toma resultado
3142        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3143        ids = toma_parametro("ids", parametros); // Toma idperfilsoft
3144        iph = toma_parametro("iph", parametros); // Toma ip
3145        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3146        cfg = toma_parametro("cfg", parametros); // Toma configuracin
3147        hdc = toma_parametro("hdc", parametros); // Toma participaciones a formatear
3148
3149        strcpy(gids, ids); // Guarda el identificador de la acción
3150        strcpy(gido, ido); // Guarda el identificador del ordenador
3151
3152        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
3153                db.GetErrorErrStr(ErrStr);
3154                return (false);
3155        }
3156        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3157                return (false); // Error al registrar notificacion
3158        }
3159
3160        if (strcmp(res, ACCION_FALLIDA) == 0) {
3161                db.Close();
3162                return (true); // Ha habido algn error en la ejecucin de la acción del cliente rembo
3163        }
3164        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph))
3165                return (false); // Error al actualiza la configuracin
3166
3167        lon = strlen(hdc);
3168        for (i = 0; i < lon; i++) {
3169                if (hdc[i] == ';')
3170                        hdc[i] = '\0';
3171        }
3172        for (i = 0; i < lon; i++) {
3173                if (*hdc != '\0') {
3174                        resul = Actualiza_ordenador_imagen(hdc, "0", gido, db);
3175                        if (!resul) {
3176                                db.Close();
3177                                return (false);
3178                        }
3179                }
3180                hdc++;
3181        }
3182        db.Close();
3183        return (true);
3184}
3185// ________________________________________________________________________________________________________
3186// Función: RESPUESTA_TomaConfiguracion
3187//
3188//              Descripción:
3189//                      Esta función responde a un comando de Toma Comfiguracin. Además actualiza la base de datos.
3190//              Parámetros:
3191//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3192//                      - parametros: parámetros del comando
3193// ________________________________________________________________________________________________________
3194int RESPUESTA_TomaConfiguracion(SOCKET s, char *parametros) {
3195        char ErrStr[200];
3196        Database db;
3197        Table tbl;
3198
3199        char *res, *der, *ids, *iph, *ido, *cfg;
3200
3201        res = toma_parametro("res", parametros); // Toma resultado
3202        der = toma_parametro("der", parametros); // Toma descripción del error ( si hubiera habido)
3203        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3204        iph = toma_parametro("iph", parametros); // Toma ip
3205        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3206        cfg = toma_parametro("cfg", parametros); // Toma configuración
3207
3208        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3209                db.GetErrorErrStr(ErrStr);
3210                return (false);
3211        }
3212        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3213                return (false); // Error al registrar notificación
3214        }
3215        if (strcmp(res, ACCION_FALLIDA) != 0) { // Ha habido algn error en la ejecución de la acción del cliente rembo
3216                if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph)) // El ordenador ha cambiado de configuración
3217                        return (false);
3218        }
3219        db.Close();
3220        return (true);
3221}
3222// ________________________________________________________________________________________________________
3223// Función: RESPUESTA_TomaHardware
3224//
3225//              Descripción:
3226//                      Esta función responde a un comando de Toma HArdware. Además actualiza la base de datos.
3227//              Parámetros:
3228//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3229//                      - parametros: parametros del comando
3230// ________________________________________________________________________________________________________
3231int RESPUESTA_TomaHardware(SOCKET s, char *parametros) {
3232        char ErrStr[200];
3233        Database db;
3234        Table tbl;
3235        char nomfiledst[512];
3236        char *res, *der, *ids, *iph, *ido, *hrd, *ipr, *rep;
3237
3238        res = toma_parametro("res", parametros); // Toma resultado
3239        der = toma_parametro("der", parametros); // Toma descripcin del error ( si hubiera habido)
3240        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3241        iph = toma_parametro("iph", parametros); // Toma ip
3242        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3243
3244        hrd = toma_parametro("hrd", parametros); // Toma nombre del archivo de inventario
3245        ipr = toma_parametro("ipr", parametros); // Dirección IP repositorio
3246        rep = toma_parametro("rep", parametros); // puerto comunicaciones
3247
3248        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3249                db.GetErrorErrStr(ErrStr);
3250                return (false);
3251        }
3252        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3253                return (false); // Error al registrar notificacion
3254        }
3255        if (strcmp(res, ACCION_FALLIDA) != 0) {
3256                sprintf(nomfiledst, "/tmp/hard-%s", iph); // Nombre del fichero destino
3257                if (recibeFichero(ipr, rep, hrd, nomfiledst)) {
3258                        if (!actualiza_hardware(db, tbl, nomfiledst, iph, ido))
3259                                return (false);
3260                } else
3261                        return (false);
3262        }
3263        db.Close();
3264        return (true);
3265}
3266//______________________________________________________________________________________________________
3267// Función: recibeFichero
3268//
3269//      Descripción:
3270//              Se trae un fichero del repositorio y lo coloca en el diretorio /tmp
3271//      Parámetros:
3272//              - nomfile : Nombre del fichero
3273//      Devuelve:
3274//              true si el proceso es correcto y false en caso contrario
3275//      Especificaciones:
3276//              En los parametros de la trama se copian el contenido del del archivo de comandos
3277// ________________________________________________________________________________________________________
3278int recibeFichero(char *ipr, char *rep, char *nomfilesrc, char *nomfiledst) {
3279        SOCKET udpsock;
3280        int blk, lsize;
3281        char *b, *l;
3282        FILE *f;
3283        int ret;
3284        struct sockaddr_in addrRepo;
3285        socklen_t iAddrSize = sizeof(addrRepo);
3286        TRAMA trama;
3287
3288        udpsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3289        if (udpsock == SOCKET_ERROR) {
3290                RegistraLog(
3291                                "*** No se ha podido crear socket para comunicación con el repositorio en módulo recibeFichero",
3292                                true);
3293                return (false);
3294        }
3295
3296        f = fopen(nomfiledst, "wb");
3297        if (!f) {
3298                RegistraLog("*** No se ha podido crear archivo", false);
3299                close(udpsock);
3300                return (false);
3301        }
3302
3303        sprintf(trama.parametros, "nfn=mandaFichero\rnfl=%s\r", nomfilesrc); // Nombre de la función a ejecutar en el  servidor de administración
3304        if (envia_comandos(udpsock, &trama, ipr, atoi(rep))) {
3305                b = &trama.arroba; // Puntero al comienzo de la trama para colocar el bloque leido
3306                l = b + sizeof(blk); // Puntero después del dato bloque para colocar los bytes leidos
3307                do {
3308                        ret = recvfrom(udpsock, (char *) &trama, LONGITUD_TRAMA, 0,
3309                                        (struct sockaddr *) &addrRepo, &iAddrSize);
3310                        if (ret) {
3311                                memcpy(&blk, b, sizeof(blk));
3312                                memcpy(&lsize, l, sizeof(lsize));
3313                                if (lsize > 0)
3314                                        lsize = fwrite(trama.parametros, 1, lsize, f); // Escribe contenido en el fichero
3315                                else {
3316                                        fclose(f);
3317                                        close(udpsock);
3318                                        return (true);
3319                                }
3320                        } else {
3321                                RegistraLog("*** Error de recepción de archivo", false);
3322                                break;
3323                        }
3324                        envia_comandos(udpsock, &trama, ipr, atoi(rep));
3325                } while (lsize > 0);
3326                fclose(f);
3327        } else {
3328                RegistraLog(
3329                                "*** Error de envío de trama al repositorio en módulo recibeFichero",
3330                                false);
3331                close(udpsock);
3332                fclose(f);
3333                return (false);
3334        }
3335        close(udpsock);
3336        return (true);
3337}
3338// ________________________________________________________________________________________________________
3339// Función: RESPUESTA_TomaSoftware
3340//
3341//              Descripción:
3342//                      Esta función responde a un comando de Inventario Software. Además actualiza la base de datos.
3343//              Parámetros:
3344//                      - s: Socket que el cliente rembo usa para comunicarse con el servidor HIDRA
3345//                      - parametros: parámetros del comando
3346// ________________________________________________________________________________________________________
3347int RESPUESTA_TomaSoftware(SOCKET s, char *parametros) {
3348        char ErrStr[200];
3349        Database db;
3350        Table tbl;
3351        char nomfiledst[512];
3352        char *res, *der, *ids, *iph, *ido, *sft, *par, *tfs, *ipr, *rep;
3353
3354        res = toma_parametro("res", parametros); // Toma resultado
3355        der = toma_parametro("der", parametros); // Toma descripción del error ( si hubiera habido)
3356        ids = toma_parametro("ids", parametros); // Toma identificador de la acción
3357        iph = toma_parametro("iph", parametros); // Toma ip
3358        ido = toma_parametro("ido", parametros); // Toma identificador del ordenador
3359
3360        sft = toma_parametro("sft", parametros); // Toma software
3361        par = toma_parametro("par", parametros); // Toma partición
3362        tfs = toma_parametro("tfs", parametros); // Toma tipo partición
3363
3364        ipr = toma_parametro("ipr", parametros); // Dirección IP repositorio
3365        rep = toma_parametro("rep", parametros); // puerto comunicaciones
3366
3367        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
3368                db.GetErrorErrStr(ErrStr);
3369                return (false);
3370        }
3371        if (!RespuestaEstandar(res, der, ids, ido, db, tbl)) {
3372                return (false); // Error al registrar notificación
3373        }
3374        if (strcmp(res, ACCION_FALLIDA) != 0) { // Ha habido algn error en la ejecución de la acción del cliente rembo
3375                sprintf(nomfiledst, "/tmp/soft-%s-%s", iph, par); // Nombre del fichero destino
3376                if (recibeFichero(ipr, rep, sft, nomfiledst)) {
3377                        if (!actualiza_software(db, tbl, nomfiledst, par, tfs, iph, ido)) // El ordenador ha cambiado de configuración
3378                                return (false);
3379                }
3380        } else
3381                return (false);
3382
3383        db.Close();
3384        return (true);
3385}
3386// ________________________________________________________________________________________________________
3387// Función: busca_comandos
3388//
3389//              Descripción:
3390//                      Esta función busca en la base de datos,comandos pendientes de ejecutar  para el ordenador cocreto
3391//              Parámetros:
3392//                      - iph: Dirección IP del ordenador
3393//                      - ido: Identificador del ordenador
3394//                      - parametros: parametros de la acción buscada
3395//                      - ids: Identificador de la acción
3396// ________________________________________________________________________________________________________
3397int busca_comandos(char* iph, char *ido, char *parametros, int *ids) {
3398        char sqlstr[1000], ErrStr[200];
3399        Database db;
3400        Table tbl, tbln;
3401
3402        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexion
3403                db.GetErrorErrStr(ErrStr);
3404                return (false);
3405        }
3406        sprintf(
3407                        sqlstr,
3408                        "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",
3409                        EJECUCION_COMANDO, ACCION_INICIADA, ACCION_SINERRORES,
3410                        ACCION_CONERRORES, 37, iph, 37);
3411        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3412                db.GetErrorErrStr(ErrStr);
3413                return (false);
3414        }
3415        if (tbl.ISEOF()) {
3416                db.Close();
3417                return (false); // No hay comandos pendientes
3418        }
3419
3420        while (!tbl.ISEOF()) { // Busca entre todas las acciones de diversos ambitos
3421
3422                if (!tbl.Get("parametros", parametros)) { // Toma parámetros
3423                        tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo parametros
3424                        return (false);
3425                }
3426
3427                if (IgualIP(parametros, iph)) { // Si existe la IP en la cadena
3428                        if (!tbl.Get("idaccion", *ids)) { // Toma identificador de la acción
3429                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3430                                return (false);
3431                        }
3432
3433                        // Comprueba que aunque el resultado es ACCION_INICIADA, este ordenador aún no ha notificado
3434                        sprintf(
3435                                        sqlstr,
3436                                        "SELECT idnotificador FROM notificaciones WHERE accionid=%d AND idnotificador=%s",
3437                                        *ids, ido);
3438                        if (!db.Execute(sqlstr, tbln)) { // Error al leer
3439                                db.GetErrorErrStr(ErrStr);
3440                                return (false);
3441                        }
3442                        if (tbln.ISEOF()) {
3443                                db.Close();
3444                                return (true); // No ha notificado este ordenador
3445                        }
3446                }
3447                tbl.MoveNext();
3448        }
3449        db.Close();
3450        return (false); // No hay mn acciones
3451}
3452// ________________________________________________________________________________________________________
3453// Función: InsertaNotificaciones
3454//
3455//
3456//              Parámetros:
3457//                      - idaccion: Identificador en la base de datos de la acción
3458//                      - idnotificador: Identificador en la base de datos de la notificación
3459//                      - accionid: Identificador de la acción padre
3460//                      - resultado: Resultado de la acción
3461//                      - db: Objeto conexión con la base de datos
3462// ________________________________________________________________________________________________________
3463int InsertaNotificaciones(int idaccion, int idnotificador, int accionid,
3464                char *resultado, Database db) {
3465
3466        struct tm* st;
3467        char ErrStr[200], sqlstr[1000];
3468        char fechahorareg[100];
3469        char descrinotificacion[100];
3470
3471        st = TomaHora();
3472        sprintf(fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3473                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3474
3475        strcpy(descrinotificacion, " ");
3476
3477        if (strcmp(resultado, ACCION_CONERRORES) == 0) {
3478                strcpy(descrinotificacion,
3479                                "Ha ocurrido algn error en la ejecución de esta tarea.");
3480                strcpy(resultado, ACCION_FALLIDA);
3481        }
3482        if (strcmp(resultado, ACCION_SINERRORES) == 0)
3483                strcpy(resultado, ACCION_EXITOSA);
3484
3485        sprintf(
3486                        sqlstr,
3487                        "INSERT INTO notificaciones (accionid,idnotificador,fechahorareg,resultado,descrinotificacion,idaccion) VALUES (%d,%d,'%s','%s','%s',%d)",
3488                        accionid, idnotificador, fechahorareg, resultado,
3489                        descrinotificacion, idaccion);
3490        if (!db.Execute(sqlstr)) { // Error al insertar
3491                db.GetErrorErrStr(ErrStr);
3492                return (false);
3493        }
3494        return (true);
3495}
3496// ________________________________________________________________________________________________________
3497// Función: comprueba_resultados
3498//
3499//
3500//              Parámetros:
3501//                      - idaccion: Identificador en la base de datos de la acción
3502//                      - db: Objeto de la base de datos
3503//
3504// ________________________________________________________________________________________________________
3505int comprueba_resultados(int idaccion, Database db) {
3506
3507        char ErrStr[200], sqlstr[1000];
3508        int numfallidas;
3509        char finalaccion[2];
3510        Table tbl;
3511
3512        sprintf(
3513                        sqlstr,
3514                        "SELECT COUNT(*) as numfallidas FROM notificaciones WHERE resultado='%s' AND accionid=%d",
3515                        ACCION_FALLIDA, idaccion);
3516        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3517                db.GetErrorErrStr(ErrStr);
3518                return (false);
3519        }
3520        if (tbl.ISEOF())
3521                return (false); // No existe registro de acciones
3522
3523        if (!tbl.Get("numfallidas", numfallidas)) { // Toma dato
3524                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3525                return (false);
3526        }
3527
3528        if (numfallidas > 0)
3529                strcpy(finalaccion, ACCION_CONERRORES);
3530        else
3531                strcpy(finalaccion, ACCION_SINERRORES);
3532
3533        sprintf(sqlstr, "UPDATE acciones SET resultado='%s' WHERE idaccion=%d",
3534                        finalaccion, idaccion);
3535        if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
3536                db.GetErrorErrStr(ErrStr);
3537                return (false);
3538        }
3539        // Comprueba si ha finalizado esta acción e inserta su notificador correspondiente
3540        return (comprueba_finalizada(idaccion, finalaccion, db));
3541}
3542// ________________________________________________________________________________________________________
3543// Función: comprueba_finalizada
3544//
3545//
3546//              Parámetros:
3547//                      - idaccion: Identificar en la base de datos de la acción
3548//                      - resultado: Resultado de la acción
3549//                      - db: Objeto conxión con la base de datos
3550// ________________________________________________________________________________________________________
3551int comprueba_finalizada(int idaccion, char *resultado, Database db) {
3552
3553        char ErrStr[200], sqlstr[1000];
3554        int numnotificaciones, tipoaccion, idnotificador;
3555        char parametros[LONGITUD_PARAMETROS], *cadenanot;
3556        char fechareg[100];
3557        int accionid, cont, i, resul, lon;
3558        Table tbl;
3559        struct tm* st;
3560
3561        sprintf(
3562                        sqlstr,
3563                        "SELECT COUNT(*) as numnotificaciones FROM notificaciones WHERE accionid=%d",
3564                        idaccion);
3565        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3566                db.GetErrorErrStr(ErrStr);
3567                return (false);
3568        }
3569        if (tbl.ISEOF())
3570                return (false); // No existe registro de acciones
3571
3572        if (!tbl.Get("numnotificaciones", numnotificaciones)) { // Toma dato
3573                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3574                return (false);
3575        }
3576
3577        sprintf(
3578                        sqlstr,
3579                        "SELECT tipoaccion,parametros,idnotificador,accionid FROM acciones WHERE idaccion=%d",
3580                        idaccion);
3581        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
3582                db.GetErrorErrStr(ErrStr);
3583                return (false);
3584        }
3585        if (tbl.ISEOF())
3586                return (true); // No existe registro de acciones
3587
3588        if (!tbl.Get("tipoaccion", tipoaccion)) { // Toma dato
3589                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3590                return (false);
3591        }
3592        if (!tbl.Get("parametros", parametros)) { // Toma dato
3593                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3594                return (false);
3595        }
3596        if (!tbl.Get("idnotificador", idnotificador)) { // Toma dato
3597                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3598                return (false);
3599        }
3600        if (!tbl.Get("accionid", accionid)) { // Toma dato
3601                tbl.GetErrorErrStr(ErrStr); // error al recuperar el campo resultado
3602                return (false);
3603        }
3604
3605        INTROaFINCAD(parametros);
3606        switch (tipoaccion) {
3607        case EJECUCION_COMANDO:
3608                cadenanot = toma_parametro("iph", parametros); // Toma cadenaip
3609                break;
3610        case EJECUCION_TAREA:
3611                cadenanot = toma_parametro("cmd", parametros); // Toma comandos
3612                break;
3613        case EJECUCION_TRABAJO:
3614                cadenanot = toma_parametro("tsk", parametros); // Toma tareas
3615                break;
3616        default:
3617                return (false);
3618        }
3619        cont = 1;
3620        lon = strlen(cadenanot);
3621        for (i = 0; i < lon; i++) {
3622                if (cadenanot[i] == ';')
3623                        cont++;
3624        }
3625        resul = true;
3626        if (numnotificaciones == cont) {
3627                st = TomaHora();
3628                sprintf(fechareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3629                                + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3630
3631                if (strcmp(resultado, ACCION_CONERRORES) == 0)
3632                        sprintf(
3633                                        sqlstr,
3634                                        "UPDATE acciones SET resultado='%s',estado='%s',fechahorafin='%s' WHERE idaccion=%d",
3635                                        ACCION_FALLIDA, ACCION_FINALIZADA, fechareg, idaccion);
3636                else
3637                        sprintf(
3638                                        sqlstr,
3639                                        "UPDATE acciones SET resultado='%s',estado='%s',fechahorafin='%s' WHERE idaccion=%d",
3640                                        ACCION_EXITOSA, ACCION_FINALIZADA, fechareg, idaccion);
3641
3642                if (!db.Execute(sqlstr)) { // Error al actualizar
3643                        db.GetErrorErrStr(ErrStr);
3644                        return (false);
3645                }
3646
3647                if (accionid > 0) { // Esto no se ejecutar si la tarea tiene un trabajo padre
3648                        resul = InsertaNotificaciones(idaccion, idnotificador, accionid,
3649                                        resultado, db);
3650                        if (resul)
3651                                return (comprueba_resultados(accionid, db));
3652                }
3653        }
3654        return (resul);
3655}
3656// ________________________________________________________________________________________________________
3657// Función: EnviaServidoresRembo
3658//
3659//              Descripción:
3660//                      Esta función envía una  trama a un servidor rembo para que sus clientes ejecuten un comando
3661//              Parámetros:
3662//                      - parametros: parametros del comando
3663//                      - cont: contador de clientes
3664// ________________________________________________________________________________________________________
3665void EnviaServidoresRembo(char * parametros, int cont) {
3666        int i, lon;
3667        char paux[20];
3668
3669        sprintf(paux, "ide=%d\r", TomaEnvio());
3670        strcat(parametros, paux); // Identificador de la sesión multicast
3671
3672        sprintf(paux, "nip=%d\r", cont);
3673        strcat(parametros, paux); // Contador de clientes a los que se envía la trama
3674
3675        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3676                if (tbsocketsSRVRMB[i].swenv == 1) { // El switch de envío está a uno, hay que enviar al servidor trama ...
3677                        strcat(parametros, "iph=");
3678                        strcat(parametros, tbsocketsSRVRMB[i].ipes);
3679                        lon = strlen(parametros);
3680                        parametros[lon - 1] = '\r'; // Quita la coma final
3681                        manda_trama_servidorrembo(tbsocketsSRVRMB[i].ip, parametros,
3682                                        tbsocketsSRVRMB[i].puertorepo);
3683                }
3684        }
3685}
3686// ________________________________________________________________________________________________________
3687// Función: manda_trama_servidorrembo
3688//
3689//              Descripción:
3690//                      Esta función envía  una  trama a un servidor rembo para que sus clientes ejecuten un comando
3691//              Parámetros:
3692//                      - ip_srvrbm: Dirección IP del servidor REMBO
3693//                      - parametros: parametros del comando
3694//                      - puertorepo: puerto del repositorio
3695// ________________________________________________________________________________________________________
3696int manda_trama_servidorrembo(char* ip_srvrbm, char *parametros, int puertorepo) {
3697        int ret;
3698        TRAMA *trama = (TRAMA*) malloc(LONGITUD_TRAMA);
3699        if (!trama)
3700                return (false);
3701        strcpy(trama->parametros, parametros);
3702        SOCKET udpsock;
3703        udpsock = UDPConnect(IPlocal);
3704        if (udpsock == INVALID_SOCKET)
3705                return (false);
3706        ret = envia_comandos(udpsock, trama, ip_srvrbm, puertorepo);
3707        close(udpsock);
3708        return (ret);
3709}
3710//_______________________________________________________________________________________________________________
3711// Función: UDPConnect
3712//
3713//              Descripción:
3714//                      Crea un socket en un puerto determinado para la conversación UDP con el repositorio
3715//              Parámetros:
3716//                      - ips: Ip local
3717//_______________________________________________________________________________________________________________
3718SOCKET UDPConnect(char *ips) {
3719        SOCKET socket_c; // Socket para hebras (UDP)
3720        struct sockaddr_in cliente;
3721        int puerto;
3722
3723        socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Crea socket para UDP
3724
3725        if (socket_c == SOCKET_ERROR)
3726                return (INVALID_SOCKET);
3727
3728        cliente.sin_addr.s_addr = inet_addr(ips); // selecciona interface
3729        cliente.sin_family = AF_INET;
3730        puerto = PUERTOMINUSER;
3731        while (puerto < PUERTOMAXUSER) { // Busca puerto libre
3732                cliente.sin_port = htons(puerto); // Puerto asignado
3733                if (bind(socket_c, (struct sockaddr *) &cliente, sizeof(cliente))
3734                                == SOCKET_ERROR)
3735                        puerto++;
3736                else
3737                        break;
3738        }
3739        if (puerto >= PUERTOMAXUSER) { // No hay puertos libres
3740                return (INVALID_SOCKET);
3741        }
3742        return (socket_c);
3743}
3744//________________________________________________________________________________________________________
3745// Función: envia_comandos
3746//
3747//              Descripción:
3748//                      Enva trama UDP
3749//              Parámetros:
3750//                      - s: socket
3751//                      - trama: El contenido de la trama
3752//                      - ipsrv: Ip del repositorio
3753//                      - puerto: puerto de conexión
3754// ________________________________________________________________________________________________________
3755int envia_comandos(SOCKET s, TRAMA* trama, char* ipsrv, int puerto) {
3756        int ret, lon;
3757        struct sockaddr_in addrRepo;
3758
3759        trama->arroba = '@'; // cabecera de la trama
3760        strcpy(trama->identificador, "JMMLCAMDJ"); // identificador de la trama
3761        trama->ejecutor = '1'; // ejecutor de la trama 1=el servidor hidra  2=el cliente hidra
3762
3763        addrRepo.sin_family = AF_INET;
3764        addrRepo.sin_port = htons((short) puerto);
3765        addrRepo.sin_addr.s_addr = inet_addr(ipsrv); //  Dirección IP repositorio
3766        Encriptar((char*) trama);
3767        lon = strlen((char*) trama);
3768        ret = sendto(s, (char *) trama, lon, 0, (struct sockaddr *) &addrRepo,
3769                        sizeof(addrRepo));
3770        if (ret == SOCKET_ERROR) {
3771                RegistraLog("***send() fallo en envío al repositorio", true);
3772                return (FALSE);
3773        }
3774        return true;
3775}
3776// ________________________________________________________________________________________________________
3777// Función: DesmarcaServidoresRembo
3778//
3779//       Descripción:
3780//               Esta función desmarca la tabla completa de servidores rembo para iniciar la cuestion de envío
3781//       Parámetros:
3782//               Ninguno
3783// ________________________________________________________________________________________________________
3784void DesmarcaServidoresRembo(void) {
3785        int i;
3786        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3787                tbsocketsSRVRMB[i].swenv = 0;
3788                tbsocketsSRVRMB[i].ipes[0] = (char) NULL;
3789        }
3790}
3791// ________________________________________________________________________________________________________
3792// Función: MarcaServidoresRembo
3793//
3794//              Descripción:
3795//                      Esta función marca la tabla de servidores Rembo y coloca la ip del cliente en el buffer
3796//              Parámetros:
3797//                      - ipsrvrmb: ip del servidor rembo
3798//                      - ipclrmb: ip del cliente rembo
3799// ________________________________________________________________________________________________________
3800void MarcaServidoresRembo(char* ipsrvrmb, char*ipclrmb) {
3801        int i, resul;
3802        for (i = 0; i < MAXIMOS_SRVRMB; i++) {
3803                resul = strcmp(tbsocketsSRVRMB[i].ip, ipsrvrmb);
3804                if (resul == 0) {// servidor rembo encontrado
3805                        strcat(tbsocketsSRVRMB[i].ipes, ipclrmb);
3806                        strcat(tbsocketsSRVRMB[i].ipes, ";");
3807                        tbsocketsSRVRMB[i].swenv = 1;
3808                        return;
3809                }
3810        }
3811}
3812// ________________________________________________________________________________________________________
3813// Función: TomaIPServidorRembo
3814//
3815//              Descripción:
3816//                      Esta función devuelve true o false dependiendo si el Servidor REMBO está en la tabla  de servidores.
3817//              Parámetros:
3818//                      - ip : La ip del servidor a buscar
3819//                      - p: parámetro de salida. Si encuentra la ip trae el puerto en la variable
3820// ________________________________________________________________________________________________________
3821BOOLEAN TomaIPServidorRembo(char *ip, int *p) {
3822        int i, j;
3823        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
3824                if (strcmp(ip, tbsockets[i].ip) == 0) { // Si existe la IP ...
3825                        strcpy(ip, tbsockets[i].ipsrvrmb);
3826                        for (j = 0; j < MAXIMOS_SRVRMB; j++) {
3827                                if (strcmp(ip, tbsocketsSRVRMB[j].ip) == 0) { // Si existe la IP ...
3828                                        *p = tbsocketsSRVRMB[j].puertorepo;
3829                                        return (TRUE);
3830                                }
3831                        }
3832                }
3833        }
3834        return (FALSE);
3835}
3836
3837// ________________________________________________________________________________________________________
3838// Función: EjecutarTarea
3839//
3840//              Descripción:
3841//                      Registra una acción (Tarea) y la envía  para su ejecución
3842//              Parámetros:
3843//                      - idtarea : Identificador de la tarea
3844//                      - accionid: identificador del trabajo padre (si existe)
3845//                      - idnotificador:  identificador del trabajo_tarea incluido en el trabajo padre (si existe)
3846//                      - idcentro: Centro propietario del trabjo padre (si existe este trabajo)
3847//                      - db: Objeto de la base de datos
3848//                      - parametros: parámetros de la acción
3849// ________________________________________________________________________________________________________
3850int EjecutarTarea(int idtarea, int accionid, int idnotificador, int idcentro,
3851                Database db, char* parametros) {
3852        char sqlstr[1000], ErrStr[200], ambito;
3853        Table tbl;
3854        int cont_comandos = 0, lon;
3855        int idcomando, idambito, idtareacomando, accionidcmd;
3856        char wambitarea[20], ambitarea[4000];
3857        char wparamtarea[20], paramtarea[1000], pids[20];
3858        int tblon[100], tbComandosidcomando[100], tbComandosambito[100],
3859                        tbComandosidnotificador[100], tbComandosidambito[100];
3860        char *tbComandosparametros[100];
3861
3862        ambitarea[0] = (char) NULL; // Inicialización
3863        strcpy(paramtarea, "cmd="); // Inicialización
3864        if (idcentro == 0) {
3865                // recupera el identificador del Centro propietario de la tarea
3866                sprintf(sqlstr, "SELECT idcentro FROM tareas WHERE idtarea=%d", idtarea);
3867                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3868                        db.GetErrorErrStr(ErrStr);
3869                        return (false);
3870                }
3871                if (tbl.ISEOF())
3872                        return (true);
3873                if (!tbl.Get("idcentro", idcentro)) { // Toma dato
3874                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3875                        return (false);
3876                }
3877        }
3878        // Recupera los comandos que forman parte de la tarea
3879        sprintf(sqlstr,
3880                        "SELECT * FROM tareas_comandos WHERE idtarea=%d ORDER by orden",
3881                        idtarea);
3882        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3883                db.GetErrorErrStr(ErrStr);
3884                return (false);
3885        }
3886        if (tbl.ISEOF())
3887                return (true);
3888
3889        // Recorre tareas-comandos
3890        while (!tbl.ISEOF()) {
3891                if (!tbl.Get("idcomando", idcomando)) { // Toma dato
3892                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3893                        return (false);
3894                }
3895                tbComandosidcomando[cont_comandos] = idcomando;
3896
3897                if (!tbl.Get("ambito", ambito)) { // Toma dato
3898                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3899                        return (false);
3900                }
3901                tbComandosambito[cont_comandos] = ambito;
3902
3903                if (!tbl.Get("idambito", idambito)) { // Toma dato
3904                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3905                        return (false);
3906                }
3907                tbComandosidambito[cont_comandos] = idambito;
3908
3909                if (!tbl.Get("parametros", parametros)) { // Toma dato
3910                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3911                        return (false);
3912                }
3913
3914                lon = strlen(parametros);
3915                tblon[cont_comandos] = lon;
3916                tbComandosparametros[cont_comandos] = (char*) malloc(lon + 20);
3917                if (tbComandosparametros[cont_comandos] == NULL)
3918                        return (false); // No hay memoria suficiente
3919
3920                strcpy(tbComandosparametros[cont_comandos], parametros);
3921
3922                if (!tbl.Get("idtareacomando", idtareacomando)) { // Toma dato
3923                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3924                        return (false);
3925                }
3926                tbComandosidnotificador[cont_comandos] = idtareacomando;
3927
3928                sprintf(wambitarea, "%d:%d;", ambito, idambito);
3929                strcat(ambitarea, wambitarea);
3930
3931                sprintf(wparamtarea, "%d;", idtareacomando);
3932                strcat(paramtarea, wparamtarea);
3933
3934                cont_comandos++;
3935                tbl.MoveNext();
3936        }
3937        lon = strlen(ambitarea);
3938        ambitarea[lon - 1] = (char) NULL; // Quita la coma final
3939
3940        lon = strlen(paramtarea);
3941        paramtarea[lon - 1] = (char) NULL; // Quita la coma final
3942
3943        char _fechahorareg[100];
3944        struct tm* st;
3945        st = TomaHora();
3946        sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
3947                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
3948
3949        sprintf(
3950                        sqlstr,
3951                        "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)",
3952                        EJECUCION_TAREA, idtarea, PROCESOS, ambitarea, _fechahorareg,
3953                        ACCION_INICIADA, ACCION_SINERRORES, idcentro, paramtarea, accionid,
3954                        idnotificador);
3955        if (!db.Execute(sqlstr)) { // Error al insertar
3956                db.GetErrorErrStr(ErrStr);
3957                return (false);
3958        }
3959        accionid = 0;
3960        // Toma identificador dela acción
3961        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3962        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3963                db.GetErrorErrStr(ErrStr);
3964                return (false);
3965        }
3966        if (!tbl.ISEOF()) { // Si existe registro
3967                if (!tbl.Get("identificador", accionid)) {
3968                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
3969                        return (false);
3970                }
3971        }
3972        int i;
3973        // Insertar acciones:comandos
3974        for (i = 0; i < cont_comandos; i++) {
3975                st = TomaHora();
3976                sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900,
3977                                st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min,
3978                                st->tm_sec);
3979                sprintf(
3980                                sqlstr,
3981                                "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)",
3982                                EJECUCION_COMANDO, tbComandosidcomando[i], PROCESOS,
3983                                tbComandosambito[i], tbComandosidambito[i], _fechahorareg,
3984                                ACCION_EXITOSA, ACCION_SINERRORES, idcentro,
3985                                tbComandosparametros[i], accionid, tbComandosidnotificador[i]);
3986                if (!db.Execute(sqlstr)) { // Error al insertar
3987                        db.GetErrorErrStr(ErrStr);
3988                        free(tbComandosparametros[i]);
3989                        return (false);
3990                }
3991                // Toma identificador dela acción
3992                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3993                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3994                        db.GetErrorErrStr(ErrStr);
3995                        return (false);
3996                }
3997                if (!tbl.ISEOF()) { // Si existe registro
3998                        if (!tbl.Get("identificador", accionidcmd)) {
3999                                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4000                                return (false);
4001                        }
4002                }
4003                sprintf(pids, "ids=%d\r", accionidcmd);
4004                strcat((char*) tbComandosparametros[i], pids); // Le ande el identificador de la acción
4005                envia_tarea(tbComandosparametros[i]);
4006                free(tbComandosparametros[i]);
4007        }
4008        return (true);
4009}
4010// ________________________________________________________________________________________________________
4011// Función: envia_tarea
4012//
4013//              Descripción:
4014//                      Esta función envía  una tarea  por la red.
4015//              Parámetros:
4016//                      - parametros: El contenido de la tarea
4017// ________________________________________________________________________________________________________
4018void envia_tarea(char* parametros) {
4019        TRAMA trama;
4020
4021        trama.arroba = '@';
4022        strncpy(trama.identificador, "JMMLCAMDJ", 9);
4023        trama.ejecutor = parametros[0];
4024        strcpy(trama.parametros, (char*) &parametros[1]);
4025        gestiona_comando(INVALID_SOCKET, trama);
4026}
4027// ________________________________________________________________________________________________________
4028// Función: EjecutarTrabajo
4029//
4030//              Descripción:
4031//                      Registra una acción (Trabajo) y la envía  para su ejecución
4032//              Parámetros:
4033//                      - idtrabajo : Identificador del trabajo
4034//                      - db: Objeto de la base de datos
4035//                      - parametros: parámetros de la acción
4036// ________________________________________________________________________________________________________
4037int EjecutarTrabajo(int idtrabajo, Database db, char*parametros) {
4038        char sqlstr[1000], ErrStr[200];
4039        Table tbl;
4040        int cont_tareas = 0, lon;
4041        int idtarea, idtrabajotarea, idcentro;
4042        char wambitrabajo[500], ambitrabajo[4000];
4043        char wparamtrabajo[20], paramtrabajo[1000];
4044        int tbTareasidtarea[100], tbTareasidnotificador[100];
4045        char ambitskwrk[500];
4046
4047        ambitrabajo[0] = (char) NULL; // Inicialización
4048        strcpy(paramtrabajo, "tsk="); // Inicialización
4049
4050        // recupera el identificador del Centro propietario de la tarea
4051        sprintf(sqlstr, "SELECT idcentro FROM trabajos WHERE idtrabajo=%d",
4052                        idtrabajo);
4053        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4054                db.GetErrorErrStr(ErrStr);
4055                return (false);
4056        }
4057        if (tbl.ISEOF())
4058                return (true);
4059        if (!tbl.Get("idcentro", idcentro)) { // Toma dato
4060                tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4061                return (false);
4062        }
4063        // Recupera las tareas que forman parte del trabajo
4064        sprintf(sqlstr,
4065                        "SELECT * FROM trabajos_tareas WHERE idtrabajo=%d ORDER by orden",
4066                        idtrabajo);
4067        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4068                db.GetErrorErrStr(ErrStr);
4069                return (false);
4070        }
4071        if (tbl.ISEOF())
4072                return (true);
4073        // Recorre trabajos-tareas
4074        while (!tbl.ISEOF()) {
4075                if (!tbl.Get("idtrabajotarea", idtrabajotarea)) { // Toma dato
4076                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4077                        return (false);
4078                }
4079                tbTareasidnotificador[cont_tareas] = idtrabajotarea;
4080
4081                if (!tbl.Get("idtarea", idtarea)) { // Toma dato
4082                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4083                        return (false);
4084                }
4085                tbTareasidtarea[cont_tareas] = idtarea;
4086
4087                if (!tbl.Get("parametros", parametros)) { // Toma dato
4088                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4089                        return (false);
4090                }
4091
4092                if (!tbl.Get("ambitskwrk", ambitskwrk)) { // Toma dato
4093                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4094                        return (false);
4095                }
4096                sprintf(wambitrabajo, "%s;", ambitskwrk);
4097                strcat(ambitrabajo, wambitrabajo);
4098
4099                sprintf(wparamtrabajo, "%d;", idtrabajotarea);
4100                strcat(paramtrabajo, wparamtrabajo);
4101
4102                cont_tareas++;
4103                tbl.MoveNext();
4104        }
4105        lon = strlen(ambitrabajo);
4106        ambitrabajo[lon - 1] = (char) NULL; // Quita la coma final
4107
4108        lon = strlen(paramtrabajo);
4109        paramtrabajo[lon - 1] = (char) NULL; // Quita la coma final
4110
4111        char _fechahorareg[100];
4112        struct tm* st;
4113        st = TomaHora();
4114        sprintf(_fechahorareg, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon
4115                        + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
4116
4117        sprintf(
4118                        sqlstr,
4119                        "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)",
4120                        EJECUCION_TRABAJO, idtrabajo, PROCESOS, ambitrabajo, _fechahorareg,
4121                        ACCION_INICIADA, ACCION_SINERRORES, idcentro, paramtrabajo);
4122        if (!db.Execute(sqlstr)) { // Error al insertar
4123                db.GetErrorErrStr(ErrStr);
4124                return (false);
4125        }
4126        int accionid = 0;
4127        // Toma identificador dela acción
4128        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
4129        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4130                db.GetErrorErrStr(ErrStr);
4131                return (false);
4132        }
4133        if (!tbl.ISEOF()) { // Si existe registro
4134                if (!tbl.Get("identificador", accionid)) {
4135                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4136                        return (false);
4137                }
4138        }
4139        int i;
4140        // Insertar acciones:tareas
4141        for (i = 0; i < cont_tareas; i++) {
4142                if (!EjecutarTarea(tbTareasidtarea[i], accionid,
4143                                tbTareasidnotificador[i], idcentro, db, parametros)) {
4144                        return (false);
4145                }
4146        }
4147        return (true);
4148}
4149// ________________________________________________________________________________________________________
4150// Función: cuestion_nuevoordenador
4151//
4152//              Descripción:
4153//                      Esta función da de alta un ordenador y un aula si el sistema está configurado para ello
4154//              Parámetros:
4155//                      - db: Objeto base de datos (ya operativo)
4156//                      - tbl: Objeto tabla
4157//                      - ido: identificador del ordenador que se dará de alta automáticamente (se devuelve)
4158//                      - nau: Nombre del grupo donde estnel ordenador( rembo.conf)
4159//                      - nor: Nombre del ordenador dado por rembo(dhcpd)
4160//                      - iph: IP del ordenador
4161//                      - mac: MAC del ordenador
4162//                      - cfg: configuración
4163//                      - ipd: ip del servidor dhcp
4164//                      - ipr: ip del servidor rembo
4165// ________________________________________________________________________________________________________
4166int cuestion_nuevoordenador(Database db, Table tbl, int*ido, char *nau,
4167                char *nor, char *iph, char *mac, char*cfg, char*ipd, char*ipr) {
4168        char sqlstr[1000], ErrStr[200];
4169        int ida, isd, isr;
4170
4171        // Recupera los datos del aula
4172        sprintf(sqlstr, "SELECT idaula FROM aulas  WHERE nombreaula= '%s'", nau);
4173
4174        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4175                db.GetErrorErrStr(ErrStr);
4176                return (false);
4177        }
4178        if (tbl.ISEOF()) { // Si NO existe el aula
4179                sprintf(sqlstr, "SELECT idaula FROM aulas  WHERE nombreaula= '%s'",
4180                                "Default");
4181                if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4182                        db.GetErrorErrStr(ErrStr);
4183                        return (false);
4184                }
4185                if (tbl.ISEOF()) { // Inserta el aula por defecto
4186                        sprintf(sqlstr, "INSERT INTO aulas (nombreaula) VALUES ('Default')");
4187                        if (!db.Execute(sqlstr)) { // Error al insertar
4188                                db.GetErrorErrStr(ErrStr);
4189                                return (false);
4190                        }
4191                        ida = 0;
4192                        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
4193                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4194                                db.GetErrorErrStr(ErrStr);
4195                                return (false);
4196                        }
4197                        if (!tbl.ISEOF()) { // Si existe registro
4198                                if (!tbl.Get("identificador", ida)) {
4199                                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4200                                        return (false);
4201                                }
4202                        }
4203                }
4204        } else {
4205                if (!tbl.Get("idaula", ida)) { // Toma dato
4206                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4207                        return (false);
4208                }
4209        }
4210        if (!Toma_idservidorres(db, tbl, ipd, ipr, &isd, &isr))
4211                return (false);
4212        if (!alta_ordenador(db, tbl, ido, nor, iph, mac, ida, isd, isr))
4213                return (false); // Alta del ordenador
4214        if (!actualiza_configuracion(db, tbl, cfg, 0, 0, iph)) { // Actualiza la configuración del ordenador
4215                return (false);
4216        }
4217        return (true);
4218}
4219// ________________________________________________________________________________________________________
4220// Función: alta_ordenador
4221//
4222//              Descripción:
4223//                      Esta funcin da de alta un ordenador
4224//              Parámetros:
4225//                      - db: Objeto base de datos (ya operativo)
4226//                      - tbl: Objeto tabla
4227//                      - mac: MAC del ordenador
4228//                      - ida: Identificador del aula
4229//                      - isd: Identificador del servidor dhcp
4230//                      - isr: Identificador del servidor rembo
4231// ________________________________________________________________________________________________________
4232int alta_ordenador(Database db, Table tbl, int* ido, char *nor, char *iph,
4233                char*mac, int ida, int isd, int isr) {
4234        char sqlstr[1000], ErrStr[200], strmac[20];
4235        int idordenador, lon, i, p;
4236
4237        // Prepara mac
4238        lon = strlen(mac);
4239        p = 0;
4240        for (i = 0; i < lon; i++) {
4241                if (mac[i] != ' ') // Si no es espacio
4242                        strmac[p++] = mac[i];
4243        }
4244        strmac[p] = (char) NULL;
4245
4246        sprintf(
4247                        sqlstr,
4248                        "INSERT INTO ordenadores(nombreordenador,ip,mac,idperfilhard,idservidordhcp,idservidorrembo,idmenu,idaula,grupoid,idconfiguracion) VALUES ('%s','%s','%s',0,%d,%d,0,%d,0,0)",
4249                        nor, iph, strmac, isd, isr, ida);
4250        if (!db.Execute(sqlstr)) { // Error al insertar
4251                db.GetErrorErrStr(ErrStr);
4252                return (false);
4253        }
4254        idordenador = 0;
4255        // Toma identificador dela acción
4256        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
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("identificador", idordenador)) {
4263                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4264                        return (false);
4265                }
4266        }
4267        *ido = idordenador;
4268        return (true);
4269}
4270// ________________________________________________________________________________________________________
4271// Función: Toma_idservidorres
4272//
4273//              Descripción:
4274//                      Esta funcin devuelve los identificadores de los servidores rembo y dhcp de un determinado ordenador
4275//              Parámetros:
4276//                              db: Objeto base de datos (ya operativo)
4277//                              tbl: Objeto tabla
4278//                              ipd: ip del servidor dhcp
4279//                              ipr: ip del servidor rembo
4280//                              isd: identificador del servidor dhcp
4281//                              isr: identificador del servidor rembo
4282// ________________________________________________________________________________________________________
4283int Toma_idservidorres(Database db, Table tbl, char*ipd, char*ipr, int*isd,
4284                int*isr) {
4285        char sqlstr[1000], ErrStr[200];
4286        int identificador_dhcp = 0;
4287        int identificador_rembo, puertorepo_rembo;
4288
4289        /* Servidor dhcp
4290         sprintf(sqlstr,"SELECT idservidordhcp FROM servidoresdhcp where ip='%s'",ipd);
4291         if(!db.Execute(sqlstr,tbl)){ // Error al leer
4292         db.GetErrorErrStr(ErrStr);
4293         return(false);
4294         }
4295         if(!tbl.ISEOF()){ // Si existe registro
4296         if(!tbl.Get("idservidordhcp",identificador_dhcp)){
4297         tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4298         return(false);
4299         }
4300         }
4301         */
4302        // Servidor rembo
4303        sprintf(
4304                        sqlstr,
4305                        "SELECT idservidorrembo,puertorepo FROM servidoresrembo where ip='%s'",
4306                        ipr);
4307        if (!db.Execute(sqlstr, tbl)) { // Error al leer
4308                db.GetErrorErrStr(ErrStr);
4309                return (false);
4310        }
4311        if (!tbl.ISEOF()) { // Si existe registro
4312                if (!tbl.Get("idservidorrembo", identificador_rembo)) {
4313                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4314                        return (false);
4315                }
4316                if (!tbl.Get("puertorepo", puertorepo_rembo)) {
4317                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4318                        return (false);
4319                }
4320        }
4321        *isd = identificador_dhcp;
4322        *isr = identificador_rembo;
4323
4324        return (true);
4325}
4326// ________________________________________________________________________________________________________
4327// Función: tomaIpRepoPort
4328//
4329//              Descripción:
4330//                      Devuelve la ip y el puerto de un repositorio
4331//              Parámetros:
4332//                              iph: ip del cliente
4333//                              ipr: ip del servidor rembo
4334//                              rep: puerto del repositorio
4335// ________________________________________________________________________________________________________
4336int tomaIpRepoPort(char *iph, char *ipr, char *rep) {
4337        char ErrStr[200], sqlstr[1000];
4338        Database db;
4339        Table tbl;
4340        char iprepositorio[16];
4341        int puertorepo;
4342
4343        // Toma las propiedades del ordenador
4344        if (!db.Open(usuario, pasguor, datasource, catalog)) { // error de conexión
4345                RegistraLog("Error de conexión con la base de datos", false);
4346                db.GetErrorErrStr(ErrStr);
4347                return (false);
4348        }
4349        // Recupera los datos del ordenador
4350        sprintf(
4351                        sqlstr,
4352                        "SELECT servidoresrembo.ip,servidoresrembo.puertorepo"
4353                                " FROM ordenadores "
4354                                " INNER JOIN  servidoresrembo ON ordenadores.idservidorrembo = servidoresrembo.idservidorrembo"
4355                                " WHERE ordenadores.ip = '%s'", iph);
4356
4357        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
4358                RegistraLog("Error al ejecutar la consulta", false);
4359                db.GetErrorErrStr(ErrStr);
4360                return (false);
4361        }
4362        if (tbl.ISEOF()) { // Si No existe registro
4363                RegistraLog("Repositorio NO encontrado", false);
4364                return (false);
4365
4366        } else {
4367                if (!tbl.Get("ip", iprepositorio)) { // Toma dato
4368                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4369                        return (false);
4370                }
4371                if (!tbl.Get("puertorepo", puertorepo)) { // Toma dato
4372                        tbl.GetErrorErrStr(ErrStr); // error al acceder al registro
4373                        return (false);
4374                }
4375        }
4376        sprintf(ipr, "%s", iprepositorio);
4377        sprintf(rep, "%d", puertorepo);
4378        db.Close();
4379        return (true);
4380}
4381//************************************************************************************************************************************************
4382// PROGRAMA PRINCIPAL (SERVICIO)
4383//***************************************************************************************************************************************************
4384int main(int argc, char *argv[]) {
4385        SOCKET socket_s; // Socket donde escucha el servidor
4386        SOCKET socket_c; // Socket de los clientes que se conectan
4387        int i;// Tamaño de la estructura de direccionamiento IP del cliente
4388        socklen_t iAddrSize;
4389        struct sockaddr_in local, cliente;
4390        //pthread_t hThread;
4391        //void *resul
4392        // Validación de parámetros
4393
4394        strcpy(szPathFileCfg, "ogAdmServer.cfg");
4395        strcpy(szPathFileLog, "ogAdmServer.log");
4396
4397        for (i = 1; (i + 1) < argc; i += 2) {
4398                if (argv[i][0] == '-') {
4399                        switch (tolower(argv[i][1])) {
4400                        case 'f':
4401                                if (argv[i + 1] != NULL)
4402                                        strcpy(szPathFileCfg, argv[i + 1]);
4403                                else {
4404                                        RegistraLog(
4405                                                        "Fallo en los parámetros: Debe especificar el fichero de configuración del servicio",
4406                                                        false);
4407                                        exit(EXIT_FAILURE);
4408                                }
4409                                break;
4410                        case 'l':
4411                                if (argv[i + 1] != NULL)
4412                                        strcpy(szPathFileLog, argv[i + 1]);
4413                                else {
4414                                        RegistraLog(
4415                                                        "Fallo en los parámetros: Debe especificar el fichero de log para el servicio",
4416                                                        false);
4417                                        exit(EXIT_FAILURE);
4418                                }
4419                                break;
4420                        default:
4421                                RegistraLog(
4422                                                "Fallo de sintaxis en los parámetros: Debe especificar -f nombre_del_fichero_de_configuración_del_servicio",
4423                                                false);
4424                                exit(EXIT_FAILURE);
4425                                break;
4426                        }
4427                }
4428        }
4429        if (szPathFileCfg == NULL) {
4430                printf("***Error. No se ha especificado fichero de configuración\n");
4431                exit(EXIT_FAILURE);
4432        }
4433        if (!TomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuración
4434                RegistraLog(
4435                                "El fichero de configuración contiene un error de sintaxis",
4436                                false);
4437                exit(EXIT_FAILURE);
4438        }
4439        pthread_mutex_init(&guardia, NULL); // Creación del mutex para control de hebras
4440
4441        for (i = 0; i < MAXIMOS_SOCKETS; i++) {
4442                tbsockets[i].ip[0] = '\0'; // Inicializa IP
4443                tbsockets[i].sock = INVALID_SOCKET; // Inicializa Socket
4444        }
4445        RegistraLog("***Inicio de sesion***", false);
4446
4447        socket_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Crea socket
4448        if (socket_s == SOCKET_ERROR) {
4449                RegistraLog("***socket() fallo:", true);
4450        }
4451        local.sin_addr.s_addr = htonl(INADDR_ANY); // selecciona interface
4452        local.sin_family = AF_INET;
4453        local.sin_port = htons(puerto); // Puerto
4454
4455        if (bind(socket_s, (struct sockaddr *) &local, // Enlaza socket
4456                        sizeof(local)) == SOCKET_ERROR) {
4457                RegistraLog("***bind() fallo:", true);
4458                exit(EXIT_FAILURE);
4459        }
4460
4461        listen(socket_s, 250); // Pone a escuchar al socket
4462        iAddrSize = sizeof(cliente);
4463
4464        while (true) { // Bucle para escuchar peticiones de clientes
4465                socket_c = accept(socket_s, (struct sockaddr *) &cliente, &iAddrSize);
4466                if (socket_c == INVALID_SOCKET) {
4467                        RegistraLog("***accept() fallo:", true);
4468                        break;
4469                }
4470                //resul=pthread_create(&hThread,NULL,GestionaConexion,(void*)&socket_c);
4471                GestionaConexion(&socket_c);
4472                /*if(resul!=0){2
4473                 RegistraLog("***Fallo al crear la hebra cliente",false);
4474                 break;
4475                 }
4476                 */
4477                //pthread_detach(hThread);
4478                close(socket_c); // Cierra la conexión con el servidor hidra
4479        }
4480        close(socket_s);
4481        exit(EXIT_SUCCESS);
4482}
Note: See TracBrowser for help on using the repository browser.