source: admin/Services/ogAdmServer/sources/ogAdmServer.cpp @ 5701de1

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 5701de1 was 1a9dea4, checked in by alonso <alonso@…>, 15 years ago

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

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