source: admin/Sources/ogAdmServer/sources/ogAdmServer.cpp @ 483ccb5

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 483ccb5 was f6b42f2, checked in by alonso <alonso@…>, 16 years ago

primeros archivos de administración

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

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