source: admin/Services/ogAdmServer/sources/ogAdmServer.cpp @ a0377eb

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 a0377eb was b0bb14f, checked in by alonso <alonso@…>, 16 years ago

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

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