source: admin/Services/ogAdmServer/sources/ogAdmServer.cpp @ 06be672

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 06be672 was 2f4f9ff, checked in by alonso <alonso@…>, 15 years ago

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

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