source: admin/Services/ogAdmClient/sources/ogAdmClient.c @ 513af22

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 513af22 was 044cd96, checked in by ramon <ramongomez@…>, 16 years ago

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

  • Property mode set to 100644
File size: 75.2 KB
Line 
1//****************************************************************************************************************************************************
2//      Aplicación OpenGNSys
3//      Autor: José Manuel Alonso.
4//      Licencia: Open Source
5//      Fichero: ogAdmClient.c
6//      Descripción:
7//              Este módulo de la aplicación OpenGNSys implementa las comunicaciones con el Cliente.
8// ****************************************************************************************************************************************************
9#include "ogAdmClient.h"
10//______________________________________________________________________________________________________
11// Función: Encripta
12//
13//       Descripción:
14//              Encripta una cadena
15//      Parámetros:
16//              - cadena: Cadena a encriptar
17//      Devuelve:
18//              - La cadena encriptada
19//______________________________________________________________________________________________________
20char* Encriptar(char *cadena)
21{
22         return(cadena);
23       
24        int i,lon;
25        char clave;
26       
27        clave = 12 & 0xFFU; // La clave elegida entre 0-255, en este caso 12
28        lon=strlen(cadena);
29        for(i=0;i<lon;i++)
30      cadena[i]=((char)cadena[i] ^ clave) & 0xFF;
31        return(cadena);
32}
33//______________________________________________________________________________________________________
34// Función: Desencripta
35//
36//       Descripción:
37//              Desencripta una cadena
38//      Parámetros:
39//              - cadena: Cadena a desencriptar
40//      Devuelve:
41//              La cadena desencriptada
42//______________________________________________________________________________________________________
43char* Desencriptar(char *cadena)
44{
45        return(cadena);
46       
47        int i,lon;
48        char clave;
49       
50        clave = 12 & 0xFFU; // La clave elegida entre 0-255, en este caso 12
51        lon=strlen(cadena);
52        for(i=0;i<lon;i++)
53                cadena[i]=((char)cadena[i] ^ clave) & 0xFF;
54        return(cadena);
55
56}
57//______________________________________________________________________________________________________
58// Función: ValidacionParametros
59//
60//       Descripción:
61//              Valida que los parametros de ejecución del programa sean correctos
62//      Parámetros:
63//              - argc: Número de argumentos
64//              - argv: Puntero a cada argumento
65//      Devuelve:
66//              true si los argumentos pasados son correctos y false en caso contrario
67//      Especificaciones:
68//              La sintaxis de los argumentos es la siguiente
69//                      -f      Archivo de configuración del cliente
70//                      -l      Archivo de logs
71//                      -d      Nivel de debuger (Mensages que se escribirán en el archivo de logs)
72//______________________________________________________________________________________________________
73int ValidacionParametros(int argc,char*argv[])
74{
75        int i;
76
77        for(i = 1; i < argc; i++){
78                if (argv[i][0] == '-'){
79                        switch (tolower(argv[i][1])){
80                                case 'f':
81                                        if (argv[i+1]!=NULL)
82                                                strcpy(szPathFileCfg, argv[i+1]);
83                                        else
84                                                return(false);  // Error en el argumento archivo de configuración
85                                        break;
86                                case 'l':
87                                        if (argv[i+1]!=NULL)
88                                                strcpy(szPathFileLog, argv[i+1]);       // Error en el argumento archivo de log
89                                        else
90                                                return(false);
91                                        break;
92                                case 'd':
93                                        if (argv[i+1]!=NULL){
94                                                ndebug=atoi(argv[i+1]);
95                                                if(ndebug<1 )
96                                                ndebug=1;       // Por defecto el nivel de debug es 1
97                                        }
98                                        else
99                                                return(false); // Error en el argumento nivel de debug
100                                        break;
101                                default:
102                                        return(false);
103                                        break;
104                        }
105                }
106        }
107        return(true);
108}
109//______________________________________________________________________________________________________
110// Función: CrearArchivoLog
111//
112//       Descripción:
113//              Abre el archivo de log para añadir registros desde el principio y si no existe lo crea de nuevo
114//      Parámetros:
115//              - szPathFileLog:        Nombre del archivo
116//      Devuelve:
117//              true si la acción ha sido correcta y false en caso contrario
118//______________________________________________________________________________________________________
119int CrearArchivoLog(char* szPathFileLog)
120{       
121        return(true);
122        FILE* FLog;
123        FLog=fopen(szPathFileLog,"wt"); // Abre de log para escritura al comienzo
124        if(FLog!=NULL){
125                fclose(FLog);
126                return(true);
127        }
128        return(false);
129}
130//______________________________________________________________________________________________________
131// Función: LeeFileConfiguracion
132//
133//       Descripción:
134//              Lee el fichero de configuración y toma el valor de los parámetros de configuración
135//      Parámetros:
136//              Ninguno
137//      Devuelve:
138//              true si todos los parámetros de configuración son correctos y false en caso contrario
139//______________________________________________________________________________________________________
140int LeeFileConfiguracion()
141{
142        long lSize;
143        char * buffer,*lineas[100],*dualparametro[2];
144        char ch[2];
145        int i,numlin,resul;
146        FILE* Fconfig;
147       
148        if(szPathFileCfg==NULL) return(false); // Nombre del fichero de configuración erróneo
149
150        Fconfig = fopen ( szPathFileCfg , "rb" );       // Abre  fichero de configuración
151        if (Fconfig==NULL)
152                return(false); // Error de apertura del fichero de configuración
153        fseek (Fconfig , 0 , SEEK_END);
154        lSize = ftell (Fconfig);        // Obtiene tamaño del fichero.
155        rewind (Fconfig);       // Coloca puntero de lectura al principio
156       
157        buffer =(char*)ReservaMemoria(lSize);   // Toma memoria para el buffer de lectura.
158        if (buffer == NULL)
159                return(false); // Error de reserva de memoria para buffer de lectura
160        fread (buffer,1,lSize,Fconfig); // Lee contenido del fichero
161        fclose(Fconfig);
162
163        //inicializar variables globales
164        IPlocal[0]='\0';        // IP local
165        Servidorhidra[0]='\0';  // IP servidor de Administración
166        Puerto[0]='\0'; // Puerto de comunicaciones con el servidor de administración
167        HIDRACHEIMAGENES[0]='\0';       // Path al directorio donde están las imágenes (en la caché)
168        HIDRASRVIMAGENES[0]='\0';       // Path al directorio donde están las imágenes (en el repositorio)
169        HIDRASRVCMD[0]='\0';    // Path del directorio del repositorio donde se depositan los comandos para el cliente
170        HIDRASCRIPTS[0]='\0';   // Path al directorio donde estan los scripts de interface con la API de funciones
171       
172        strcpy(ch,"\n");        // Carácter delimitador (salto de linea)
173        numlin=SplitParametros(lineas,buffer,ch); // Toma lineas del  fichero
174        for (i=0;i<numlin;i++){
175                strcpy(ch,"="); // Caracter delimitador
176                SplitParametros(dualparametro,lineas[i],ch); // Toma nombre del parametros
177                resul=strcmp(dualparametro[0],"ServerIP");
178                if(resul==0)
179                        strcpy(Servidorhidra,dualparametro[1]);
180                else{
181                        resul=strcmp(dualparametro[0],"Puerto");
182                        if(resul==0)
183                                strcpy(Puerto,dualparametro[1]);
184                        else{
185                                resul=strcmp(dualparametro[0],"ClientScripts");
186                                if(resul==0)
187                                        strcpy(HIDRASCRIPTS,dualparametro[1]);
188                                else{
189                                        resul=strcmp(dualparametro[0],"UrlMenu");
190                                        if(resul==0)
191                                                strcpy(URLMENU,dualparametro[1]);
192                                        else
193                                                return(false);
194                                }
195                        }
196                }
197        }
198        return(true);
199}
200//______________________________________________________________________________________________________
201// Función: Log
202//
203//       Descripción:
204//              Registra un mensaje en el archivo de log y lo muestra por la consola
205//      Parámetros:
206//              - msg: Contenido del mensaje
207//______________________________________________________________________________________________________
208void Log(char* msg)
209{
210        time_t rawtime;
211        struct tm * timeinfo;
212               
213        time (&rawtime);
214        timeinfo=gmtime(&rawtime);
215
216/*
217        FILE* FLog;
218        FLog=fopen(szPathFileLog,"at"); // Archivo de log
219        if(FLog!=NULL)
220                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);
221        fclose(FLog);   
222*/
223        // Lo muestra por consola
224        sprintf(msgcon,"echo '%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);
225        system(msgcon);
226       
227}
228//______________________________________________________________________________________________________
229// Función: UltimoError
230//
231//       Descripción:
232//              Almacena el último error producido y lo registra en el log
233//      Parámetros:
234//              - herror: Código del error
235//              - msg: Descripción del error
236//              - modulo: Función donde se produjo el error
237//______________________________________________________________________________________________________
238void UltimoError(int herror,char*modulo)
239{
240        e.herror=herror;
241        if(herror>MAXERROR){
242                strcpy(e.msg,tbErrores[MAXERROR]);
243        }
244        else
245                strcpy(e.msg,tbErrores[herror]);       
246        strcpy(e.modulo,modulo);       
247        sprintf(msglog,"Error en el Servicio: %d.-(%s) en modulo %s",e.herror,e.msg,e.modulo);
248        Log(msglog);
249}
250
251//______________________________________________________________________________________________________
252// Función: UltimoErrorScript
253//
254//       Descripción:
255//              Almacena el último error producido al ejecutar un script de la API y lo registra en el log
256//      Parámetros:
257//              - herror: Código del error
258//              - msg: Descripción del error
259//              - modulo: Función donde se produjo el error
260//______________________________________________________________________________________________________
261void UltimoErrorScript(int herror,char*modulo)
262{
263        e.herror=herror;
264        if(herror>MAXERRORSCRIPT){
265                strcpy(e.msg,tbErrores[MAXERRORSCRIPT+1]);
266        }
267        else
268                strcpy(e.msg,tbErroresScripts[herror]);
269        strcpy(e.modulo,modulo);       
270        sprintf(msglog,"Error al ejecutar Script %d.-(%s) en modulo %s",e.herror,e.msg,e.modulo);
271        Log(msglog);
272}
273//______________________________________________________________________________________________________
274// Función: INTROaFINCAD
275//
276//      Descripción:
277//              Cambia los INTROS (\r) por caracteres fin de cadena ('\0') en una cadena
278//      Parámetros:
279//              - parametros : La cadena a explorar
280// ________________________________________________________________________________________________________
281void INTROaFINCAD(char* parametros)
282{
283        int lon,i;
284        lon=strlen(parametros);
285        for(i=0;i<lon;i++){
286                if(parametros[i]=='\r') parametros[i]='\0';
287        }
288}
289//______________________________________________________________________________________________________
290// Función: TomaParametro
291//
292//      Descripción:
293//              Devuelve el valor de un parametro incluido en la trama.
294//              El formato del protocolo es: "nombre_parametro=valor_parametro"
295//      Parámetros:
296//              - nombre_parametro: Es el nombre del parnetro a recuperar
297//              - parametros: Es la matriz que contiene todos los parámetros
298//      Devuelve:
299//              Un puntero al valor del parámetro
300// ________________________________________________________________________________________________________
301char * TomaParametro(char* nombre_parametro,char *parametros)
302{
303        int i=0;
304        char* pos;
305
306        for(i=0;i<LONGITUD_PARAMETROS_TRAMA-4;i++){
307                if(parametros[i]==nombre_parametro[0]){
308                        if(parametros[i+1]==nombre_parametro[1]){
309                                if(parametros[i+2]==nombre_parametro[2]){
310                                        if(parametros[i+3]=='='){
311                                                pos=&parametros[i+4];
312                                                return(pos);
313                                        }
314                                }
315                        }
316                }
317        }
318        return(NULL);
319}
320//______________________________________________________________________________________________________
321// Función: SplitParametros
322//
323//      Descripción:
324//              Trocea una cadena según un carnter delimitador, Devuelve el número de trozos
325//      Parámetros:
326//              - trozos: Array de punteros a cadenas
327//              - cadena: Cadena a trocear
328//              - ch: Carácter delimitador
329//      Devuelve:
330//              Número de trozos en que se ha troceado la cadena
331// ________________________________________________________________________________________________________
332int SplitParametros(char **trozos,char *cadena, char * ch)
333{
334        int w=0;
335        char* token;
336
337        token= strtok(cadena,ch); // Trocea según delimitador
338        while( token != NULL ){
339                trozos[w++]=token;
340                token=strtok(NULL,ch); // Siguiente token
341        }
342        trozos[w++]=token;
343        return(w-1); // Devuelve el número de trozos
344}
345//______________________________________________________________________________________________________
346// Función: EjecutarScript
347//
348//       Descripción:
349//              Ejecuta un script de la shell creando un proceso hijo para ello
350//      Parámetros:
351//              - script: Nombre del script de la  shell
352//              - parametros: Parámetros que se le pasarán al script
353//              - salida: Recoge la salida por pantalla que genera el script
354//              - swasci: Filtra la respuesta del script:
355//                                       true=Elimina de la respuesta caracteres menores de asci 32
356//                                       false= No los elimina                                 
357//      Devuelve:
358//              Código de error de la ejecución. ( Ver tabla de código de errores en la documentación)
359//      Especificaciones:
360//              El parámetro salida recoge la salida por pantalla que se genera en la ejecución del script siempre que
361//              sea disinto de NULL, esto es, si al llamar a la función este parámetro es NULL no se recogerá dicha salida.
362//______________________________________________________________________________________________________
363int EjecutarScript ( char *script,char * parametros,char *salida,int swasci)
364{
365        int  descr[2];  /* Descriptores de E y S de la turbería */
366        int  bytesleidos;       /* Bytes leidos en el mensaje */
367        int resul;
368        int estado;     
369        pid_t  pid;
370        char buffer[512];
371        pipe (descr);
372        int i,nargs;
373   
374        if(ndebug>2){
375                sprintf(msglog,"Ejecución del script: %s",script);
376                Log(msglog);
377        }
378       
379        nargs=SplitParametros(argumentos,parametros," "); // Crea matriz de los argumentos del scripts
380        for(i=nargs;i<MAXARGS;i++){
381                argumentos[i]=NULL;
382        }
383   
384        if(ndebug>2){
385                for(i=0;i<nargs;i++){
386                        sprintf(msglog,"Parámetro %d del script: %s",i,argumentos[i]);
387                        Log(msglog);
388                }
389        }
390       
391        if((pid=fork())==0){
392                /* Proceso hijo que ejecuta el script */
393                close (descr[LEER]);
394                dup2 (descr[ESCRIBIR], 1);
395                close (descr[ESCRIBIR]);
396                resul=execv(script,argumentos);
397                //resul=execlp (script, script, argumentos[0],argumentos[1],NULL);   
398                exit(resul);   
399        }
400        else {
401                if (pid ==-1){
402                        sprintf(msglog,"***Error en la creación del proceso hijo pid=%d",pid);
403                        Log(msglog);
404                        return(-1);
405                }
406                /* Proceso padre que lee la salida del script */
407                close (descr[ESCRIBIR]);
408                bytesleidos = read (descr[LEER], buffer, 512);
409                while(bytesleidos>0){
410                        if(salida!=(char*)NULL){ // Si se solicita retorno de información...                   
411                                buffer[bytesleidos]='\0';
412                                for(i=bytesleidos-1;i>=0;i--){
413                                        if(buffer[i]<32 && swasci) // Caracter Asci menor de 32
414                                                buffer[i]='\0';
415                                }
416                                strcat(salida,buffer);
417                        }
418                        bytesleidos = read (descr[LEER], buffer, 512);
419                }
420                close (descr[LEER]);
421                if(ndebug>2){
422                        sprintf(msglog,"Información devuelta %s",salida);
423                        Log(msglog);
424                }
425                //kill(pid,SIGQUIT);
426                waitpid(pid,&estado,0); 
427                resul=WEXITSTATUS(estado);
428                if(ndebug>2){
429                        sprintf(msglog,"Estatus de finalización del script:%d",resul);
430                        Log(msglog);
431                }   
432                return(resul);
433        }
434        return(-1);
435}
436//______________________________________________________________________________________________________
437// Función: ReservaMemoria
438//
439//       Descripción:
440//              Reserva memoria para una variable
441//      Parámetros:
442//              - lon:  Longitud en bytes de la reserva
443//      Devuelve:
444//              Un puntero a la zona de memoria reservada que ha sido previamente rellena con zeros o nulos
445//______________________________________________________________________________________________________
446char* ReservaMemoria(int lon)
447{
448        char *mem;
449        mem=(char*)malloc(lon);
450        if(mem!=NULL)
451                memset(mem,0,lon);
452        return(mem);
453}
454//______________________________________________________________________________________________________
455// Función: TCPConnect
456//
457//       Descripción:
458//              Crea un socket y lo conecta a un servidor
459//      Parámetros:
460//              - ips : La Dirección IP del servidor
461//              - port : Puerto para la comunicación
462//      Devuelve:
463//              Un socket para comunicaciones por protocolo TCP
464//______________________________________________________________________________________________________
465SOCKET TCPConnect(char *ips,char* port)
466{
467        SOCKET s;
468    struct sockaddr_in server;
469
470        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
471        if (s == INVALID_SOCKET){
472                return (INVALID_SOCKET);
473        }
474        server.sin_family = AF_INET;
475        server.sin_port = htons((short)atoi(port));
476        server.sin_addr.s_addr = inet_addr(ips);
477
478        if (connect(s, (struct sockaddr *)&server, sizeof(server)) == INVALID_SOCKET)
479                return (INVALID_SOCKET);
480               
481        return(s);
482}
483//______________________________________________________________________________________________________
484// Función: TCPClose
485//
486//       Descripción:
487//              Cierra una conexión establecida a través de un socket
488//      Parámetros:
489//              - s : El socket que implementa la conexión
490//______________________________________________________________________________________________________
491void TCPClose(SOCKET s){
492        close(s);
493}
494//______________________________________________________________________________________________________
495// Función: AbreConexionTCP
496//
497//       Descripción:
498//              Abre la conexión entre el cliente y el  servidor de administración
499//      Parámetros:
500//              - ips : La Dirección IP del servidor
501//              - port : Puerto para la comunicación
502//      Devuelve:
503//              Un socket para comunicaciones por protocolo TCP con el servidor de administración
504//______________________________________________________________________________________________________
505int AbreConexionTCP()
506{
507        BOOL swloop=true;
508        int vez=0;             
509
510        while(swloop){                 
511                sock=TCPConnect(Propiedades.servidorhidra,Propiedades.puerto);
512                if(sock!= INVALID_SOCKET){
513                        return(true);
514                }
515                if(swloop){
516                        vez++;
517                        if (vez>MAXCNX){
518                                swloop=false;
519                                UltimoError(2,"AbreConexionTCP()");
520                                return(false); 
521                        }
522                }
523                sleep(5); // Espera dos cinco antes de intentar una nueva conexión con el Servidor de Administración
524        }
525        return(true);
526}
527//______________________________________________________________________________________________________
528// Función: CierraConexionTCP
529//
530//       Descripción:
531//              Cierra la conexión entre el cliente y el  servidor de administración
532//______________________________________________________________________________________________________
533void CierraConexionTCP()
534{
535        TCPClose(sock);
536}
537//______________________________________________________________________________________________________
538// Función: EnviaTramasHidra
539//
540//       Descripción:
541//              Envía una trama TCP al Servidor de Administración
542//      Parámetros:
543//              s: socket TCP
544//              trama: contenido a  enviar
545//      Devuelve:
546//              true si el envío ha sido correcto o false en caso contrario
547//______________________________________________________________________________________________________
548int EnviaTramasHidra(SOCKET s,TRAMA *trama)
549{
550        int lon;
551       
552        trama->arroba='@';      // cabecera de la trama
553        strcpy(trama->identificador,"JMMLCAMDJ");       // identificador de la trama
554        trama->ejecutor='1';    // Origen del envío  1=el servidor de administración  2=el cliente  3=el repositorio de imágenes
555                               
556        lon=strlen(trama->parametros);  // Compone la trama
557        lon+=sprintf(trama->parametros+lon,"iph=%s\r",Propiedades.IPlocal);     // Ip del ordenador
558        lon+=sprintf(trama->parametros+lon,"ido=%s\r",Propiedades.idordenador); // Identificador del ordenador
559        return(TCPWrite(s,trama));
560}
561//______________________________________________________________________________________________________
562// Función: RecibeTramasHidra
563//
564//       Descripción:
565//              Recibe una trama TCP del servidor de Administración
566//      Parámetros:
567//              s: socket TCP
568//              trama: contenido a  enviar
569//      Devuelve:
570//              true si el envío ha sido correcto o false en caso contrario
571//______________________________________________________________________________________________________
572int RecibeTramasHidra(SOCKET s,TRAMA *trama)
573{
574        return(TCPRead(s,trama));
575}
576//______________________________________________________________________________________________________
577// Función: TCPWrite
578//
579//       Descripción:
580//              Envia una trama por la red (TCP)
581//      Parámetros:
582//              s: socket TCP
583//              trama: contenido a  enviar
584//      Devuelve:
585//              true si el envío ha sido correcto o false en caso contrario
586//______________________________________________________________________________________________________
587int TCPWrite(SOCKET s,TRAMA* trama)
588{
589        int nLeft,idx,ret;
590       
591        Encriptar((char*)trama);
592        nLeft = strlen((char*)trama);
593        idx = 0;
594        while(nLeft > 0){
595                ret = send(s,(char*)&trama[idx], nLeft, 0);
596                if (ret == 0)
597                        break;
598                else
599                        if (ret == SOCKET_ERROR){
600                                return(false);
601                        }
602                nLeft -= ret;
603                idx += ret;
604        }
605        return(true);
606}
607//______________________________________________________________________________________________________
608// Función: TCPRead
609//
610//       Descripción:
611//              Recibe una trama por la red (TCP)
612//      Parámetros:
613//              s: socket TCP
614//              trama: contenido a  enviar
615//      Devuelve:
616//              true si el envío ha sido correcto o false en caso contrario
617//______________________________________________________________________________________________________
618int TCPRead(SOCKET s,TRAMA* trama)
619{
620        int ret;
621
622        ret = recv(s,(char*)trama,LONGITUD_TRAMA,0);
623        if (ret == 0) // conexión cerrada por parte del cliente (Graceful close)
624                return (false);
625        else{
626                if (ret == SOCKET_ERROR){
627                        return (false);
628                }
629                else{ // Datos recibidos
630                        Desencriptar((char*)trama);
631                        trama->parametros[ret-11]='\0'; // Coloca caracter fin de cadena en trama
632                        return(true);
633                }
634        }
635       
636}
637//______________________________________________________________________________________________________
638// Función: UDPConnect
639//
640//       Descripción:
641//              Crea un socket UDP para la comunicación con su repositorio
642//      Parámetros:
643//              Ninguno
644//      Devuelve:
645//              Un socket para comunicaciones por protocolo UDP
646//______________________________________________________________________________________________________
647SOCKET UDPConnect()
648{
649        SOCKET socket_c;
650
651        socket_c = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
652        if (socket_c == SOCKET_ERROR)
653                return (INVALID_SOCKET);
654        return(socket_c);
655}
656//______________________________________________________________________________________________________
657// Función: EnviaTramaRepo
658//
659//       Descripción:
660//              Envía una trama UDP a su repositorio de imágenes
661//      Parámetros:
662//              s: socket UDP
663//              trama: contenido a  enviar
664//              iprepo: Dirección IP del repositorio
665//              puertorepo: Puerto de destino donde el repositorio espera la trama
666//      Devuelve:
667//              true si el envío ha sido correcto o false en caso contrario
668//______________________________________________________________________________________________________
669int EnviaTramaRepo(SOCKET s,TRAMA* trama, char* iprepo,char *puertorepo)
670{
671        int ret,lon;
672        struct sockaddr_in  addrRepo;
673         
674        trama->arroba='@';      // cabecera de la trama
675        strcpy(trama->identificador,"JMMLCAMDJ");       // identificador de la trama
676        trama->ejecutor='2';    // Origen del envío  1=el servidor  2=el cliente  3=el repositorio de imágenes
677                               
678        lon=strlen(trama->parametros);  // Compone la trama
679        lon+=sprintf(trama->parametros+lon,"iph=%s\r",Propiedades.IPlocal);     // Ip local del ordenador
680        lon+=sprintf(trama->parametros+lon,"ido=%s\r",Propiedades.idordenador); // identificador del ordenador
681       
682        addrRepo.sin_family = AF_INET;
683    addrRepo.sin_port = htons((short)atoi(puertorepo)); //  Puerto del repositorio
684    addrRepo.sin_addr.s_addr = inet_addr(iprepo); //  Dirección IP del repositorio
685       
686        Encriptar((char*)trama); // Encripta la trama
687        ret = sendto(s,(char *)trama,lon+11,0,(struct sockaddr *)&addrRepo, sizeof(addrRepo));
688    if (ret == SOCKET_ERROR)
689                return(false);
690        return true;
691}
692//______________________________________________________________________________________________________
693// Función: RecibeTramaRepo
694//
695//       Descripción:
696//              Recibe una trama UDP de su repositorio de imágenes
697//      Parámetros:
698//              s: socket UDP con el que se envío anteriormente una trama al repositorio
699//      Devuelve:
700//              true si la receción ha sido correcta o false en caso contrario
701//______________________________________________________________________________________________________
702int RecibeTramaRepo(SOCKET s)
703{
704        int ret;
705        struct sockaddr_in addrRepo;
706       
707        socklen_t iAddrSize = sizeof(addrRepo);
708        ret = recvfrom(s,(char *)trama, LONGITUD_TRAMA,0,(struct sockaddr *)&addrRepo,&iAddrSize);
709        if (ret != SOCKET_ERROR){
710                Desencriptar((char*)trama);     // Desencripta la trama
711                return(true);
712        }
713        return(false);
714}
715//______________________________________________________________________________________________________
716// Función: CreateTextFile
717//
718//      Descripción:
719//              Crea un fichero de texto local y escribe en él cierto contenido
720//      Parámetros:
721//              - nomfile: Nombre del fichero
722//              - texto: Texto a escribir en el fichero
723//      Devuelve:
724//              - La longitud en bytes del contenido escrito
725//______________________________________________________________________________________________________
726long CreateTextFile(char *nomfile,char *texto)
727{
728        long lSize;
729        FILE *f;
730        f = fopen(nomfile,"wt");
731        if(!f){ // El fichero por algún motivo no ha podido crearse
732                UltimoError(3,"CreateTextFile()");
733                return(0);
734        }
735        lSize=strlen(texto);
736        fwrite(texto,1,lSize,f);        // Escribe el contenido del fichero
737        fclose(f);
738        return(lSize);
739}
740//______________________________________________________________________________________________________
741// Función: ExisteFichero
742//
743//      Descripción:
744//              Comprueba si un archivo existe en su repositorio
745//      Parámetros:
746//              - nomfile : Nombre del fichero
747//      Devuelve:
748//              true si el archivo existe o false en caso contrario
749// ________________________________________________________________________________________________________
750int ExisteFichero(char *nomfile)
751{
752        SOCKET udpsock;
753        int res;
754       
755        udpsock=UDPConnect();
756        if (udpsock == INVALID_SOCKET){
757                UltimoError(15,"ExisteFichero()");
758                return(false);
759        }
760        sprintf(trama->parametros,"nfn=ExisteFichero\rnfl=%s\r",nomfile);       // Nombre de la función a ejecutar en el  servidor de administración
761        if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){
762                res=RecibeTramaRepo(udpsock);
763                close(udpsock);
764                if(res)
765                        return(GestionTramas(trama));
766        }
767        else{
768                UltimoError(16,"ExisteFichero()");
769                return(false);
770        }
771        return(true);
772}
773//______________________________________________________________________________________________________
774// Función: RemoveFile
775//
776//      Descripción:
777//              Elimina un fichero del repositorio
778//      Parámetros:
779//              - nomfile : Nombre del fichero
780//      Devuelve:
781//              true si el archivo se ha eliminado correctamente o false en caso contrario
782// ________________________________________________________________________________________________________
783int RemoveFile(char *nomfile)
784{
785        SOCKET udpsock;
786        int res;
787       
788        udpsock=UDPConnect();
789        if (udpsock == INVALID_SOCKET){
790                UltimoError(15,"RemoveFile()");
791                return(false);
792        }
793        sprintf(trama->parametros,"nfn=EliminaFichero\rnfl=%s\r",nomfile);      // Nombre de la función a ejecutar en el  servidor de administración
794        if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){
795                res=RecibeTramaRepo(udpsock);
796                close(udpsock);
797                if(res)
798                        return(GestionTramas(trama));
799        }
800        else{
801                UltimoError(16,"RemoveFile()");
802                return(false);
803        }
804        return(true);
805}
806//______________________________________________________________________________________________________
807// Función: LoadTextFile
808//
809//      Descripción:
810//              Lee un fichero del repositorio
811//      Parámetros:
812//              - nomfile : Nombre del fichero
813//      Devuelve:
814//              true si el proceso es correcto y false en caso contrario
815//      Especificaciones:
816//              En los parametros de la trama se copian el contenido del del archivo de comandos               
817// ________________________________________________________________________________________________________
818int LoadTextFile(char *nomfile)
819{
820        SOCKET udpsock;
821        int res;
822        char *txt;
823               
824        udpsock=UDPConnect();
825        if (udpsock == INVALID_SOCKET){
826                UltimoError(15,"LoadTextFile()");
827                return(false);
828        }
829        sprintf(trama->parametros,"nfn=LeeFicheroTexto\rnfl=%s\r",nomfile);     // Nombre de la función a ejecutar en el  servidor de administración
830        if(EnviaTramaRepo(udpsock,trama,Propiedades.iprepo,Propiedades.puertorepo)){
831                res=RecibeTramaRepo(udpsock);
832                close(udpsock);
833                if(res){
834                        if(GestionTramas(trama)){
835                                txt=TomaParametro("txt",trama->parametros); // Toma contenido del fichero de  comandos
836                                strcpy(trama->parametros,txt);
837                                if(ndebug>4){
838                                        sprintf(msglog,"Archivo de comando:\r%s",trama->parametros);
839                                        Log(msglog);
840                                }
841                                return(true); // Devuelve contrenido del fichero
842                        }
843                        else{
844                                UltimoError(3,"LoadTextFile()");
845                                return(false);                         
846                        }
847                }
848                else{
849                        UltimoError(16,"LoadTextFile()");
850                        return(false);
851                }                               
852        }
853        else{
854                UltimoError(16,"LoadTextFile()");
855                return(false);
856        }
857}
858//______________________________________________________________________________________________________
859// Función: ProcesaComandos
860//
861//      Descripción:
862//              Espera comando desde el Servidor de Administración para ejecutarlos
863//      Parámetros:
864//              Ninguno
865//      Devuelve:
866//              true si el archivo se ha eliminado correctamente o false en caso contrario
867// ________________________________________________________________________________________________________
868int ProcesaComandos()
869{
870                sprintf(filecmd,"/comandos/CMD_%s",Propiedades.IPlocal);        // Nombre del fichero de comandos               
871                if(ExisteFichero(filecmd))      // Borra fichero de comandos si previamente exista de anteriores procesos
872                        RemoveFile(filecmd);
873                if(!DisponibilidadComandos(true)){      // Notifica  al servidor de Adminsitración su disponibilidad para recibir comandos
874                        UltimoError(0,"ProcesaComandos()");     
875                        return(false); 
876                }
877                PRCCMD=true;
878                while(PRCCMD){  // Bucle de espera de comandos interactivos
879                        if(ExisteFichero(filecmd)){     // Busca fichero de comandos
880                                Log("Comando recibido desde el Servidor de Administración");
881                                if(!LoadTextFile(filecmd)){     // Toma comando
882                                        UltimoError(1,"ProcesaComandos()");
883                                        return(false);
884                                }
885                                GestionTramas(trama);   // Analiza la trama y ejecuta el comando
886                                Log("Procesa comandos pendientes");
887                                ComandosPendientes(); // Bucle para procesar comandos pendientes
888                                Log("Disponibilidad para comandos interactivos activada ...");                         
889                                if(!DisponibilidadComandos(true)){      // Notifica  al servidor de Administración su disponibilidad para recibir comandos
890                                        UltimoError(0,"ProcesaComandos()");     
891                                        return(false);
892                                }
893                                if(!RemoveFile(filecmd)){       // Lo elimina
894                                        UltimoError(0,"ProcesaComandos()");
895                                        return(false);
896                                }
897                        }
898                        sleep(5);       // Espera 5 segundos antes de volver a esperar comandos
899                }
900                return(true);
901}
902//______________________________________________________________________________________________________
903// Función: DisponibilidadComandos
904//
905//      Descripción:
906//              Notifica al servidor su disponibilidad a recibir comandos ( Lgica negativa )
907//      Parámetros:
908//              - swdis : Indica disponibilidad si es true y NO disponibilidad en caso de ser false
909//      Devuelve:
910//              true si el proceso es correcto y false en caso contrario
911// ________________________________________________________________________________________________________
912int DisponibilidadComandos(int swdis)
913{
914                int lon;
915
916                lon=sprintf(trama->parametros,"nfn=DisponibilidadComandos\r");
917                if(!swdis)
918                        lon+=sprintf(trama->parametros+lon,"swd=0\r");  // No disponible                               
919                else
920                        lon+=sprintf(trama->parametros+lon,"swd=1\r");  // Disponible
921                       
922                if(AbreConexionTCP()){
923                        if(!EnviaTramasHidra(sock,trama)){
924                                UltimoError(21,"DisponibilidadComandos()"); // No se pudo recuperar la configuración hardware
925                                return(false);
926                        }
927                        if(!RecibeTramasHidra(sock,trama)){
928                                UltimoError(22,"DisponibilidadComandos()"); // No se pudo recuperar la configuración hardware
929                                return(false);
930                        }
931                        CierraConexionTCP();
932                        GestionTramas(trama);   // Analiza la trama
933                }
934                else{
935                        UltimoError(2,"DisponibilidadComandos()");     
936                        return(false);
937                }
938                return(true);
939}
940//______________________________________________________________________________________________________
941// Función: GestionTramas
942//
943//      Descripción:
944//              Gestiona las tramas recibidas por la red
945//      Parámetros:
946//              - trama : Una trama recibida
947//      Devuelve:
948//              true o false dependiendo del éxito en la ejecución del comandoo si se trata de una trama
949//              del Servidor de Administración o bien del resultado de la petición de información al repositorio
950// ________________________________________________________________________________________________________
951int GestionTramas(TRAMA *trama)
952{
953        TRAMA *nwtrama=NULL;
954        int res;
955        char *nombrefuncion;
956        INTROaFINCAD(trama->parametros);
957        nombrefuncion=TomaParametro("nfn",trama->parametros);
958        nwtrama=(TRAMA*)ReservaMemoria(LONGITUD_TRAMA); // Reserva buffer  para la trama        devuelta               
959        if(!nwtrama){
960                UltimoError(1,"GestionTramas()");
961                return(false);
962        }
963        if(ndebug>4){
964                sprintf(msglog,"Gestión de tramas.-Función a ejecutar:%s",nombrefuncion);
965                Log(msglog);
966        }
967        // Mensajes entre el cliente y el Servidor de Administración
968        res=strcmp(nombrefuncion,"Apagar");
969        if(res==0)
970                return(Apagar(trama,nwtrama));
971
972        res=strcmp(nombrefuncion,"Arrancar");
973        if(res==0)
974                return(Arrancar(trama,nwtrama));
975                       
976        res=strcmp(nombrefuncion,"Reiniciar");
977        if(res==0)
978                return(Reiniciar(trama,nwtrama));
979                       
980        res=strcmp(nombrefuncion,"RESPUESTA_InclusionCliente");
981        if(res==0)
982                return(RESPUESTA_InclusionCliente(trama));
983                       
984        res=strcmp(nombrefuncion,"Actualizar");
985        if(res==0)
986                return(Actualizar());           
987               
988        res=strcmp(nombrefuncion,"NoComandosPtes");
989        if(res==0)
990                return(NoComandosPtes());
991                       
992        res=strcmp(nombrefuncion,"Cortesia");
993        if(res==0)
994                return(Cortesia());                     
995                                       
996       
997        res=strcmp(nombrefuncion,"ExecShell");
998        if(res==0)
999                return(ExecShell(trama,nwtrama));                       
1000                       
1001        res=strcmp(nombrefuncion,"CrearPerfilSoftware");
1002        if(res==0)
1003                return(CrearPerfilSoftware(trama,nwtrama));                     
1004
1005        res=strcmp(nombrefuncion,"RestaurarImagen");
1006        if(res==0)
1007                return(RestaurarImagen(trama,nwtrama));                 
1008       
1009        res=strcmp(nombrefuncion,"TomaConfiguracion");
1010        if(res==0)
1011                return(TomaConfiguracion(trama,nwtrama));               
1012               
1013        res=strcmp(nombrefuncion,"InventarioHardware");
1014        if(res==0)
1015                return(InventarioHardware(trama,nwtrama));             
1016               
1017        res=strcmp(nombrefuncion,"InventarioSoftware");
1018        if(res==0)
1019                return(InventarioSoftware(trama,nwtrama));             
1020
1021        res=strcmp(nombrefuncion,"ParticionaryFormatear");
1022        if(res==0)
1023                return(ParticionaryFormatear(trama,nwtrama));                           
1024                       
1025        // Mensajes entre el cliente y el repositorio           
1026        res=strcmp(nombrefuncion,"Respuesta_ExisteFichero");
1027        if(res==0){
1028                res=atoi(TomaParametro("res",trama->parametros));
1029                return(res);
1030        }
1031                       
1032        res=strcmp(nombrefuncion,"Respuesta_EliminaFichero");
1033        if(res==0){
1034                res=atoi(TomaParametro("res",trama->parametros));
1035                return(res);
1036        }
1037               
1038        res=strcmp(nombrefuncion,"Respuesta_LeeFicheroTexto");
1039        if(res==0){
1040                res=atoi(TomaParametro("res",trama->parametros));
1041                return(res);
1042        }                       
1043
1044        UltimoError(4,"GestionTramas()");
1045        return(false); 
1046}
1047//______________________________________________________________________________________________________
1048// Función: Cortesia
1049//
1050//       Descripción:
1051//               Respuesta estandar del Servidor de Administración
1052//      Parámetros:
1053//              Ninguno
1054//      Devuelve:
1055//              true siempre
1056//      Especificaciones:
1057//              Esta función se ejecuta de forma estandar para cerrar la conversación con el Servidor de Administración
1058//______________________________________________________________________________________________________
1059int Cortesia(){
1060         return(true);
1061}
1062//______________________________________________________________________________________________________
1063// Función: NoComandosPtes
1064//
1065//       Descripción:
1066//               Conmuta el switch de los comandos pendientes y lo pone a false
1067//      Parámetros:
1068//              Ninguno
1069//      Devuelve:
1070//              true siempre
1071//      Especificaciones:
1072//              Cuando se ejecuta esta función se sale del bucle que recupera los comandos pendientes en el servidor y
1073//              el cliente pasa a a estar disponible para recibir comandos desde el éste.
1074//______________________________________________________________________________________________________
1075int NoComandosPtes(){
1076        CMDPTES=false; // Corta el bucle de comandos pendientes
1077        return(true);
1078}
1079//______________________________________________________________________________________________________
1080// Función: TomaIPlocal
1081//
1082//       Descripción:
1083//              Recupera la IP local
1084//      Parámetros:
1085//              Ninguno
1086//      Devuelve:
1087//              Una cadena con el valor de la IP en formato xxx.xxx.xxx.xxx
1088//      Especificaciones:
1089//              En caso de no encontrar la IP o generarse algún error se devuelve la dirección 0.0.0.0
1090//______________________________________________________________________________________________________
1091int TomaIPlocal()
1092{
1093        int herror;
1094       
1095        sprintf(cmdshell,"%s/getIPAddress",HIDRASCRIPTS);
1096        herror=EjecutarScript (cmdshell,NULL,IPlocal,true);     
1097        if(herror){
1098                UltimoErrorScript(herror,"TomaIPlocal()"); // Se ha producido algún error
1099                return(false);
1100        }
1101        return(true);
1102}
1103//______________________________________________________________________________________________________
1104// Función: InclusionCliente
1105//       Descripción:
1106//              Abre una sesión en el servidor de administración y registra al cliente en el sistema
1107//      Parámetros:
1108//              Ninguno
1109//      Devuelve:
1110//              true si el registro ha tenido éxito o false en caso contrario
1111//______________________________________________________________________________________________________
1112int InclusionCliente()
1113{
1114        int lon;       
1115        char *parametroscfg;
1116       
1117        parametroscfg=(char*)ReservaMemoria(256);
1118        if(!parametroscfg){
1119                UltimoError(1,"InclusionCliente()"); // No se pudo reservar memoria
1120                return(false);
1121        }
1122       
1123        char *disco=(char*)ReservaMemoria(2);
1124        sprintf(disco,"1"); // Siempre el disco 1
1125        parametroscfg=LeeConfiguracion(disco);  // Toma configuración
1126       
1127        if(ndebug>3){
1128                sprintf(msglog,"CONFIGURACION=%s",parametroscfg);
1129                Log(msglog);
1130        }
1131       
1132        if(!parametroscfg){
1133                UltimoError(18,"InclusionCliente()"); // No se pudo recuperar la configuración hardware
1134                return(false);
1135        }
1136        lon=sprintf(trama->parametros,"nfn=InclusionCliente\r");        // Nombre de la función a ejecutar en el servidor de Adminsitración
1137        lon+=sprintf(trama->parametros+lon,"cfg=%s\r",parametroscfg);   // Configuración de los Sistemas Operativos del cliente
1138        if(AbreConexionTCP()){
1139                Log("Enviando peticion de inclusion al Servidor de Administración");
1140                if(!EnviaTramasHidra(sock,trama)){
1141                        UltimoError(21,"InclusionCliente()"); // No se pudo recuperar la configuración hardware
1142                        return(false);
1143                }
1144                Log("Recibiendo respuesta del Servidor de Administración");
1145                if(!RecibeTramasHidra(sock,trama)){
1146                        UltimoError(22,"InclusionCliente()"); // No se pudo recuperar la configuración hardware
1147                        return(false);
1148                }
1149                CierraConexionTCP();
1150                if(!GestionTramas(trama)){      // Analiza la trama
1151                        UltimoError(0,"InclusionCliente()");
1152                        return(false);         
1153                }
1154                return(true);
1155        }
1156        else{
1157                UltimoError(2,"InclusionCliente()"); // No se pudo conectar con el servidor de administración
1158                return(false);
1159        }               
1160        return(true);                           
1161}
1162//______________________________________________________________________________________________________
1163// Función: RESPUESTA_InclusionCliente
1164//
1165//       Descripción:
1166//              Respuesta del servidor de administración a la petición de inicio enviando los datos identificativos del cliente y otras configuraciones
1167//      Parámetros:
1168//              trama:  Trama recibida por el cliente desde el Servidor de Administración
1169//      Devuelve:
1170//              true si el registro ha tenido éxito o false en caso contrario
1171//______________________________________________________________________________________________________
1172int RESPUESTA_InclusionCliente(TRAMA *trama)
1173{
1174        strcpy(Propiedades.idordenador,TomaParametro("ido",trama->parametros)); // Identificador del ordenador
1175        strcpy(Propiedades.nombreordenador,TomaParametro("npc",trama->parametros));     //  Nombre del ordenador
1176        strcpy(Propiedades.idaula,TomaParametro("ida",trama->parametros));      //  Identificador del aula a la que pertenece
1177        strcpy(Propiedades.idperfilhard,TomaParametro("ifh",trama->parametros));        // Identificador del perfil hardware del ordenador
1178        strcpy(Propiedades.servidorhidra,TomaParametro("hrd",trama->parametros));       // Dirección IP del servidor de Administración
1179        strcpy(Propiedades.puerto,TomaParametro("prt",trama->parametros));              // Puerto de comunicación con el servidor de Administración
1180        strcpy(Propiedades.iprepo,TomaParametro("ipr",trama->parametros));      // Dirección IP del repositorio
1181        strcpy(Propiedades.puertorepo,TomaParametro("repr",trama->parametros)); // Puerto de comunicación con el repositorio
1182
1183        // Guarda items del menú
1184        char* cabmenu=TomaParametro("cmn",trama->parametros);
1185        if (cabmenu){
1186                swmnu=true;
1187                char *auxCab[15];
1188                SplitParametros(auxCab,cabmenu,"&");    // Caracter separador de los elementos de un item
1189                strcpy(CabMnu.titulo,auxCab[0]);        // Tìtulo del menú
1190                strcpy(CabMnu.coorx,auxCab[1]); // Coordenada x del menú público
1191                strcpy(CabMnu.coory,auxCab[2]); // Coordenada y del menú público
1192                strcpy(CabMnu.modalidad,auxCab[3]);     // Modalidad de columnas del menú público
1193                strcpy(CabMnu.scoorx,auxCab[4]);        // Coordenada x del menú privado
1194                strcpy(CabMnu.scoory,auxCab[5]);        // Coordenada y del menú privado
1195                strcpy(CabMnu.smodalidad,auxCab[6]);    // Modalidad de columnas del menú privado
1196                strcpy(CabMnu.resolucion,auxCab[7]);    // Resolución de pantalla
1197        }
1198        /*char* menu=TomaParametro("mnu",trama->parametros);     // Menú estandar
1199       
1200        char* auxMenu[MAXITEMS],auxItem[10];
1201        int iMnu=SplitParametros(auxMenu,menu,"?"); // Caracter separador de  los item
1202        int i,nitem;
1203       
1204        for( i = 0; i<iMnu; i++){
1205                struct s_Item Item;
1206                nitem=SplitParametros(auxItem,auxMenu[i],"&");  // Caracter separador de los elementos de un item
1207                strcpy(Item.idaccionmenu,auxItem[0]);   // Identificador de la acción
1208                strcpy(Item.urlimg,auxItem[1]); // Url de la imagen del item
1209                strcpy(Item.literal,auxItem[2]);        // Literal del item
1210                strcpy(Item.tipoitem,auxItem[3]);       // Tipo de item ( Público o privado )
1211                strcpy(Item.tipoaccion,auxItem[4]);     // Tipo de acción ( Procedimiento,Tarea oTrabajo )
1212                tbMenu[i]=Item;
1213        }
1214        contitems=i;    // Número de items totales de los dos menús
1215        */
1216        return(true);
1217}
1218//______________________________________________________________________________________________________
1219// Función: ComandosPendientes
1220//
1221//       Descripción:
1222//               Búsqueda de acciones pendientes en el  servidor de administración
1223//______________________________________________________________________________________________________
1224int ComandosPendientes()
1225{
1226        CMDPTES=true;
1227        while(CMDPTES){
1228                sprintf(trama->parametros,"nfn=ComandosPendientes\r");  // Nombre de la función a ejecutar en el  servidor de administración
1229                if(AbreConexionTCP()){
1230                        if(!EnviaTramasHidra(sock,trama)){
1231                                UltimoError(21,"ComandosPendientes()"); // No se pudo recuperar la configuración hardware
1232                                return(false);
1233                        }
1234                        if(!RecibeTramasHidra(sock,trama)){
1235                                UltimoError(22,"ComandosPendientes()"); // No se pudo recuperar la configuración hardware
1236                                return(false);
1237                        }
1238                        CierraConexionTCP();
1239                        GestionTramas(trama);   // Analiza la trama
1240                }
1241                else{
1242                        UltimoError(2,"ComandosPendientes()"); // No se pudo conectar con el servidor de Administración
1243                        return(false);
1244                }
1245        }
1246        CMDPTES=false;
1247        return(true);
1248}
1249//_____________________________________________________________________________________________________
1250// Función: Arrancar
1251//
1252//       Descripción:
1253//              Contesta ante un comando de arrancar
1254//      Parámetros:
1255//              - trama: Trama recibida con las especificaciones del comando
1256//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1257//      Devuelve:
1258//              true siempre
1259//_____________________________________________________________________________________________________
1260int Arrancar(TRAMA *trama,TRAMA *nwtrama)
1261{
1262        sprintf(nwtrama->parametros,"nfn=RESPUESTA_Arrancar\r");                                       
1263        return(RespuestaEjecucionComando(trama,nwtrama,true)); 
1264}
1265//_____________________________________________________________________________________________________
1266// Función: Apagar
1267//
1268//       Descripción:
1269//              Apaga el cliente
1270//      Parámetros:
1271//              - trama: Trama recibida con las especificaciones del comando
1272//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1273//      Devuelve:
1274//              true si el proceso fue correcto o false en caso contrario
1275//_____________________________________________________________________________________________________
1276int Apagar(TRAMA *trama,TRAMA *nwtrama)
1277{
1278        int res;
1279
1280        sprintf(nwtrama->parametros,"nfn=RESPUESTA_Apagar\r");                                 
1281        res=RespuestaEjecucionComando(trama,nwtrama,true);     
1282        strcpy(cmdshell,"poweroff");
1283        system(cmdshell);
1284        return(res);
1285}
1286//______________________________________________________________________________________________________
1287// Función: Reiniciar
1288//
1289//       Descripción:
1290//              Reinicia el cliente
1291//      Parámetros:
1292//              - trama: Trama recibida con las especificaciones del comando
1293//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1294//      Devuelve:
1295//              true si el proceso fue correcto o false en caso contrario
1296//______________________________________________________________________________________________________
1297int Reiniciar(TRAMA *trama,TRAMA *nwtrama)
1298{
1299        int res;
1300       
1301        sprintf(nwtrama->parametros,"nfn=RESPUESTA_Reiniciar\r");                                       
1302        res=RespuestaEjecucionComando(trama,nwtrama,true);     
1303        strcpy(cmdshell,"reboot");
1304        system(cmdshell);
1305        return(res);
1306}
1307//______________________________________________________________________________________________________
1308// Función: Actualizar
1309//
1310//       Descripción:
1311//              Actualiza los datos de un ordenador  como si volviera a solicitar la entrada  en el sistema al  servidor de administración
1312//      Parámetros:
1313//              - trama: Trama recibida con las especificaciones del comando
1314//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1315//      Devuelve:
1316//              true si el proceso fue correcto o false en caso contrario
1317//______________________________________________________________________________________________________
1318int Actualizar()
1319{
1320        int res;
1321       
1322        res=InclusionCliente();
1323        return(res);
1324}
1325//______________________________________________________________________________________________________
1326// Función: CrearPerfilSoftware
1327//
1328//       Descripción:
1329//              Genera una imagen de una partición
1330//      Parámetros:
1331//              - trama: Trama recibida con las especificaciones del comando
1332//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1333//      Devuelve:
1334//              true si el proceso fue correcto o false en caso contrario
1335//_____________________________________________________________________________________________________
1336int CrearPerfilSoftware(TRAMA*trama,TRAMA*nwtrama)
1337{
1338                int res=0;
1339                char *wparticion=TomaParametro("par",trama->parametros);        // Partición de donde se crear el perfil
1340                char *widperfilsoft=TomaParametro("ifs",trama->parametros);     // Perfil software a crear
1341                char *widperfilhard=TomaParametro("ifh",trama->parametros);     // Perfil hardware del ordenador
1342                char *wnemonico=TomaParametro("nem",trama->parametros); // Nemónico del S.O. de la partición
1343                               
1344                char *disco=(char*)ReservaMemoria(2);
1345                sprintf(disco,"1"); // Siempre el disco 1
1346                                       
1347                char pathperfil[250];
1348                sprintf(pathperfil,"%s/%s",HIDRACHEIMAGENES,wnemonico); // Path del perfil creado       
1349                       
1350                char fileperfil[64];
1351                sprintf(fileperfil,"PS%s_PH%s",widperfilsoft,widperfilhard);    // Nombre de la imagen ( del perfil creado)
1352               
1353                char filemasterboot[64];
1354                sprintf(filemasterboot,"PS%s_PH%s.msb",widperfilsoft,widperfilhard);    // Idem para el sector de arranque MBR
1355                res=CrearPerfil(disco,fileperfil,pathperfil,wparticion,Propiedades.iprepo);
1356                Log("Finalizada la creacion del perfil software");
1357                int lon;
1358                lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_CrearPerfilSoftware\r");
1359                lon+=sprintf(nwtrama->parametros+lon,"ifs=%s\r",widperfilsoft);         
1360                lon+=sprintf(nwtrama->parametros+lon,"ifh=%s\r",widperfilhard);         
1361                RespuestaEjecucionComando(trama,nwtrama,res);   
1362                return(res);   
1363}
1364//______________________________________________________________________________________________________
1365// Función: CrearPerfil
1366//
1367//       Descripción:
1368//              Crea una imagen de una partición
1369//      Parámetros:
1370//              -disco          Disco a clonar  1,2,3..
1371//              -fileimg        Nombre de la imagen
1372//              -pathimg        Ruta de la imagen
1373//              -particion      Partición a clonar
1374//              -iprepo Dirección IP del repositorio ( Si es la IP local el repositorio será la caché)
1375//      Devuelve:
1376//              true si el proceso fue correcto o false en caso contrario
1377//______________________________________________________________________________________________________
1378int CrearPerfil(char* disco,char* fileimg,char* pathimg,char* particion,char*iprepo)   
1379{
1380        int herror;
1381        sprintf(cmdshell,"%s/createImage",HIDRASCRIPTS);
1382        sprintf(parametros,"%s %s %s %s %s","createImage",disco,particion,"REPO",fileimg);
1383       
1384        if(ndebug>3){
1385                sprintf(msglog,"Creando Perfil Software disco:%s, partición:%s, Repositorio:%s, Imagen:%s, Ruta:%s",disco,particion,Propiedades.iprepo,fileimg,"");
1386                Log(msglog);
1387        }
1388       
1389        herror=EjecutarScript(cmdshell,parametros,NULL,true);
1390        if(herror){
1391                UltimoErrorScript(herror,"CrearPerfil()");       // Se ha producido algún error
1392                return(false);
1393        }
1394        else
1395                return(true);
1396}
1397//______________________________________________________________________________________________________
1398// Función: Nemonico
1399//
1400//       Descripción:
1401//              Devuelve el código de un nemonico de S.O.
1402//      Parámetros:
1403//              -nem            Nemonico del S.O.
1404//      Devuelve:
1405//              El código del nemónico
1406//______________________________________________________________________________________________________
1407int Nemonico(char* nem)
1408{
1409        if(strcmp(nem,"MsDos")==0)
1410                return(MsDos);
1411        if(strcmp(nem,"Win98")==0)
1412                return(Win98);
1413        if(strcmp(nem,"Win2K")==0)
1414                return(Win2K);
1415        if(strcmp(nem,"WinXP")==0)
1416                return( WinXP);
1417        if(strcmp(nem,"Linux")==0)
1418                return(Linux);
1419        return(0);
1420}
1421//______________________________________________________________________________________________________
1422// Función: RestaurarImagen
1423//
1424//       Descripción:
1425//              Restaura una imagen en una partición
1426//      Parámetros:
1427//              - trama: Trama recibida con las especificaciones del comando
1428//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1429//      Devuelve:
1430//              true si el proceso fue correcto o false en caso contrario
1431//______________________________________________________________________________________________________
1432int RestaurarImagen(TRAMA*trama,TRAMA*nwtrama)
1433{
1434                int res=0;
1435                char *wparticion=TomaParametro("par",trama->parametros);        // partición de donde se crear el perfil
1436                char *widimagen=TomaParametro("idi",trama->parametros); // Identificador de la imagen           
1437                char *widperfilsoft=TomaParametro("ifs",trama->parametros);     // Perfil software a crear
1438                char *widperfilhard=TomaParametro("ifh",trama->parametros);     // Perfil hardware del  ordenador
1439                //char *widcentro=TomaParametro("idc",trama->parametros);       // Identificador del Centro
1440                //char *wtipopar=TomaParametro("tpa",trama->parametros);        // Tipo de partición
1441                char *wnemonico=TomaParametro("nem",trama->parametros); // Nemonico del S.O.  contenido en la partición
1442                //char *wswrestauraimg=TomaParametro("swr",trama->parametros);  // Indica si la imagen a restaurar contiene un S.O. distinto al actual
1443                //char *widsoftincremental=TomaParametro("icr",trama->parametros);      // Cadena con los identificadores de lsoftware incremental
1444                char *wpathimagen=TomaParametro("pth",trama->parametros);       // Indica si la imagen se descargar de la caché(cache) o del servidor(net)
1445                if(wpathimagen=='\0') wpathimagen="1";  // Por defecto de caché
1446               
1447                char *disco=(char*)ReservaMemoria(2);
1448                sprintf(disco,"1"); // Siempre el disco 1               
1449                                       
1450                char *compres=(char*)ReservaMemoria(10);
1451                sprintf(compres,"gzip"); // Método de compresión               
1452               
1453                char *mettran=(char*)ReservaMemoria(10);
1454                sprintf(mettran,"unicast"); // Método de transferencia por defecto
1455                                               
1456                int idxpath=atoi(wpathimagen);
1457                if(!CACHEEXISTS) idxpath=2;     // Sin no existe cache siempre desde el servidor
1458                //if(wswrestauraimg=="O")
1459                //      res=reparticiona((int)wparticion,wtipopar);     // Reparticiona si la imagen va a una partición distinta a la original
1460                if(res==0){
1461                        char pathperfil[250];
1462                        if(idxpath==2){
1463                                sprintf(pathperfil,"%s/%s",HIDRASRVIMAGENES,wnemonico);
1464                        }
1465                        else{
1466                                if(idxpath==1){
1467                                        sprintf(pathperfil,"%s/%s",HIDRACHEIMAGENES,wnemonico);                                 
1468                                }
1469                        }
1470                        char fileperfil[64];
1471                        sprintf(fileperfil,"PS%s_PH%s",widperfilsoft,widperfilhard);    // Nombre del fichero del perfil creado
1472                        char filemasterboot[64];
1473                        sprintf(filemasterboot,"PS%s_PH%s.msb",widperfilsoft,widperfilhard);    // Idem para el sector de arranque MBR                 
1474                        res=RestaurandoImagen(disco,compres,mettran,fileperfil,pathperfil,wparticion,Propiedades.iprepo);
1475                        // Toma la nueva configuración
1476                        char *parametroscfg=LeeConfiguracion(disco);
1477                        Log("Finalizada la restauracion de imagen");
1478
1479                        int lon;                       
1480                        lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_RestaurarImagen\r");     
1481                        lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg);         
1482                        lon+=sprintf(nwtrama->parametros+lon,"idi=%s\r",widimagen);     
1483                        lon+=sprintf(nwtrama->parametros+lon,"par=%s\r",wparticion);   
1484                        RespuestaEjecucionComando(trama,nwtrama,res);   
1485                        return(res);           
1486                }
1487                return(false);
1488}
1489//______________________________________________________________________________________________________
1490// Función: RestaurandoImagen
1491//
1492//       Descripción:
1493//              Restaura na imagen en una partición
1494//      Parámetros:
1495//              -disco          Disco a clonar  1,2,3..
1496//              -fileimg        Nombre de la imagen
1497//              -pathimg        Ruta de la imagen
1498//              -particion      Partición a clonar
1499//              -iprepo Dirección IP del repositorio ( Si es la IP local el repositorio será la caché)
1500//      Devuelve:
1501//              true si el proceso fue correcto o false en caso contrario
1502//____________________________________________________________________________________________________
1503int RestaurandoImagen(char* disco,char* compres,char* mettran,char* fileimg,char* pathimg,char* particion,char*iprepo)   
1504{
1505        int herror;
1506       
1507        sprintf(cmdshell,"%s/restoreImage",HIDRASCRIPTS);
1508        sprintf(parametros," %s %s %s %s %s","restoreImage",disco,particion,iprepo,fileimg);
1509
1510        if(ndebug>3){
1511                sprintf(msglog,"Restaurando Imagen disco:%s, partición:%s, Repositorio:%s, Imagen:%s",disco,particion,Propiedades.iprepo,fileimg);
1512                Log(msglog);
1513        }
1514       
1515        herror=EjecutarScript(cmdshell,parametros,NULL,true);
1516        if(herror){
1517                UltimoErrorScript(herror,"RestaurandoImagen()");        // Se ha producido algún error
1518                return(false);
1519        }
1520        else
1521                return(true);
1522}
1523
1524//______________________________________________________________________________________________________
1525// Función: ParticionaryFormatear
1526//
1527//       Descripción:
1528//              Modifica la tabla de particiones del sector de arranque master y formatea particiones
1529//      Parámetros:
1530//              - trama: Trama recibida con las especificaciones del comando
1531//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1532//      Devuelve:
1533//              true si el proceso fue correcto o false en caso contrario
1534//____________________________________________________________________________________________________
1535int ParticionaryFormatear(TRAMA*trama,TRAMA*nwtrama)
1536{
1537        int res,i,parfor;
1538        char* parametroscfg;
1539        char ch[2],*parhdc[8];
1540        char *PrimaryPartitions=TomaParametro("ppa",trama->parametros);
1541        char *LogicalPartitions=TomaParametro("lpa",trama->parametros);
1542        char *HDCleanPartition=TomaParametro("hdc",trama->parametros);
1543
1544        char *disco=(char*)ReservaMemoria(2);
1545        sprintf(disco,"1"); // Siempre el disco 1
1546       
1547        Log("Creando o modificando tabla de particiones");
1548        res=Particionar(disco,PrimaryPartitions,LogicalPartitions); // Creando las particiones
1549        if(res){
1550                strcpy(ch,";"); // Caracter delimitador
1551                parfor=SplitParametros(parhdc,HDCleanPartition,ch);
1552                for(i = 0; i<parfor; i++){ // Formateando particiones
1553                        res=Formatear(disco,parhdc[i]);
1554                        if(!res) break;
1555                }
1556        }
1557        Log("Finalizado el particionado y formateado de particiones");
1558        parametroscfg=LeeConfiguracion(disco);  // Toma la nueva configuración
1559       
1560        int lon;
1561        lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_ParticionaryFormatear\r");               
1562        lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg);
1563        RespuestaEjecucionComando(trama,nwtrama,res);   
1564       
1565        return(res);
1566}
1567//______________________________________________________________________________________________________
1568// Función: Particionar
1569//
1570//       Descripción:
1571//              Modifica la tabla de particiones del sector de arranque master pero SIN formatear ninguna partición
1572//      Parámetros:
1573//              - PrParticion: Cadena con la sintaxis de particionado de las particiones primarias
1574//              - LoParticion: Cadena con la sintaxis de particionado de las particiones secundarias
1575//      Devuelve:
1576//              true si el proceso fue correcto o false en caso contrario
1577//______________________________________________________________________________________________________
1578int Particionar(char* disco,char* PrParticion,char* LoParticion)
1579{
1580        if (strlen(PrParticion)>0){
1581                if(Particionando(disco,PrParticion,"createPrimaryPartitions")){ // Particiones Primarias
1582                        if (strlen(LoParticion)>0)
1583                                return(Particionando(disco,PrParticion,"createLogicalPartitions"));     // Particiones Logicas
1584                        else
1585                                return(true);
1586                }
1587                else
1588                        return(false);
1589        }
1590        if (strlen(LoParticion)>0)
1591                return(Particionando(disco,PrParticion,"createLogicalPartitions"));
1592        else
1593                return(false);
1594}
1595//______________________________________________________________________________________________________
1596// Función: Particionando
1597//
1598//       Descripción:
1599//              Modifica la tabla de particiones del sector de arranque master pero SIN formatear ninguna partición
1600//      Parámetros:
1601//              - disco: Disco en el que se modificará la tabla de particiones 1,2,3..
1602//              - SintaxParticion: Cadena con la sintaxis de particionado de las particiones primarias
1603//              - script: Nombre del script que se ejecutará
1604//      Devuelve:
1605//              true si el proceso fue correcto o false en caso contrario
1606//      Especificaciones:
1607//              Esta función es auxiliar de la anterior y es llamda por esta en dos ocasiones, para las particiones Primarias y Lógicas
1608//______________________________________________________________________________________________________
1609int Particionando(char* disco,char* stxParticion,char* script)
1610{       
1611        int herror;
1612       
1613        sprintf(cmdshell,"%s/%s",HIDRASCRIPTS,script);
1614        sprintf(parametros," %s %s %s",script,disco,stxParticion);
1615        if(ndebug>1){
1616                sprintf(msglog,"Modificando tabla de particiones:%s disco:%s, cadena:%s",script,disco,stxParticion);
1617                Log(msglog);
1618        }
1619        herror=EjecutarScript(cmdshell,parametros,NULL,true);
1620        if(herror){
1621                UltimoErrorScript(herror,"Particionar()");       // Se ha producido algún error
1622                return(false);
1623    }
1624    else
1625                return(true);
1626}
1627//______________________________________________________________________________________________________
1628// Función: Formatear
1629//
1630//       Descripción:
1631//              Formatea una partición
1632//      Parámetros:
1633//              - disco: Número del disco
1634//              - particion: Número de partición a formatear
1635//      Devuelve:
1636//              true si el proceso fue correcto o false en caso contrario
1637//______________________________________________________________________________________________________
1638int Formatear(char* disco,char* particion)
1639{
1640        int herror;
1641
1642        sprintf(cmdshell,"%s/FormatFs",HIDRASCRIPTS);   
1643        sprintf(parametros," %s %s %s","FormatFs",disco,particion);
1644        herror=EjecutarScript(cmdshell,parametros,NULL,true);
1645        if(herror){
1646            UltimoErrorScript(herror,"Formatear()");     // Se ha producido algún error
1647                return(false);
1648    }
1649        return(true);
1650}
1651//______________________________________________________________________________________________________
1652// Función: SetCachePartitionSize
1653//
1654//      Descripción:
1655//              Dimensiona el tamaño de la caché
1656//      Parámetros:
1657//              - t : Tamaño a asignar de la caché
1658//      Devuelve:
1659//              true si el proceso fue correcto o false en caso contrario
1660// ________________________________________________________________________________________________________
1661int SetCachePartitionSize(int t)
1662{
1663        return(true);
1664}
1665//___________________________________________________________________________________________________
1666//
1667// 
1668//______________________________________________________________________________________________________
1669// Función: AutoClienteHidra
1670//
1671//      Descripción:
1672//              Ejecuta un fichero autoexec preparado para  el cliente
1673// ________________________________________________________________________________________________________
1674int AutoexecClienteHidra()
1675{
1676        sprintf(fileini,"/autoexec/INI_%s",Propiedades.IPlocal);        // Nombre del fichero autoexec         
1677        if(ExisteFichero(fileini)){
1678                if(LoadTextFile(fileini)){ // Lee fichero autoexec             
1679                        GestionTramas(trama);   // Analiza la trama
1680                }
1681                else{
1682                        UltimoError(6,"AutoexecClienteHidra()");
1683                        return(false);
1684                }
1685        }
1686        return(true);
1687}
1688//______________________________________________________________________________________________________
1689// Función: LeeConfiguracion
1690//
1691//      Descripción:
1692//              Recupera la configuración de particiones del ordenador
1693//      Parámetros:
1694//              disco:  Disco a analizar 1,2,3..
1695//      Devuelve:
1696//              Una cadena con la configuración del cliente (ver manual)
1697// ________________________________________________________________________________________________________
1698char* LeeConfiguracion(char* disco)
1699{
1700        int herror;
1701        char *cadenaparticiones;
1702        char *nomso;
1703       
1704        cadenaparticiones=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDA);
1705        sprintf(cmdshell,"%s/listPrimaryPartitions",HIDRASCRIPTS);     
1706        sprintf(parametros," %s %s","listPrimaryPartitions",disco);
1707        herror=EjecutarScript(cmdshell,parametros,cadenaparticiones,true);
1708        if(herror){
1709            UltimoErrorScript(herror,"LeeConfiguracion()");      // Se ha producido algún error
1710                return(NULL);
1711    }
1712        struct s_Particiones *tbcfg[MAXPARTICIONES];
1713        char *duplasparticiones[MAXPARTICIONES],*duplaparticion[2];
1714       
1715        int iPar=SplitParametros(duplasparticiones,cadenaparticiones," ");      // Caracter separatorio de los elementos de un item
1716        int i,j;
1717        for( i = 0; i<iPar; i++){
1718                SplitParametros(duplaparticion,duplasparticiones[i],":");
1719                tbcfg[i]=(struct s_Particiones*)ReservaMemoria(sizeof(struct s_Particiones)); // Toma espacio para tabla de configuraciones
1720                strcpy(tbcfg[i]->tipopart,duplaparticion[0]); // Tipo de partición
1721                strcpy(tbcfg[i]->tamapart,duplaparticion[1]); // Tamaño de partición
1722                sprintf(tbcfg[i]->numpart,"%d",i+1); // Número de partición
1723               
1724                for(j=0;j<ntiposo;j++){
1725                        if(strcmp(tiposos[j].tipopart,duplaparticion[0])==0 && strcmp(tiposos[j].tipopart,"LINUX-SWAP")!=0 && strcmp(tiposos[j].tipopart,"EMPTY")!=0){
1726                                nomso=TomaNomSO(disco,i+1);
1727                                if(nomso!=NULL){ // Averigua qué sistema operativo está instalado en la partición
1728                                        strcpy(tbcfg[i]->tiposo,tiposos[j].tiposo); // Nombre S.O.
1729                                        strcpy(tbcfg[i]->nombreso,nomso); // Nombre completo S.O.
1730                                }
1731                                else{
1732                                        strcpy(tbcfg[i]->tiposo,""); // Nombre S.O.
1733                                        strcpy(tbcfg[i]->nombreso,""); // Nombre completo S.O.
1734                                }
1735                                break;
1736                        }
1737                }
1738        }
1739        char *cfg=ReservaMemoria(LONGITUD_CONFIGURACION);
1740        if(!cfg){
1741                UltimoError(1,"LeeConfiguracion()");
1742                return(NULL);
1743        }
1744        int lon=0;
1745        for( i = 0; i<iPar; i++){
1746                lon+=sprintf(cfg+lon,"@cfg\n");
1747                lon+=sprintf(cfg+lon,"tiposo=%s\n",tbcfg[i]->tiposo);   
1748                lon+=sprintf(cfg+lon,"tipopart=%s\n",tbcfg[i]->tipopart);
1749                lon+=sprintf(cfg+lon,"tamapart=%s\n",tbcfg[i]->tamapart);
1750                lon+=sprintf(cfg+lon,"numpart=%s\n",tbcfg[i]->numpart);         
1751                lon+=sprintf(cfg+lon,"nombreso=%s\t",tbcfg[i]->nombreso);
1752        }
1753        return(cfg);
1754}
1755//______________________________________________________________________________________________________
1756// Función: TomaNomSO
1757//
1758//      Descripción:
1759//              Recupera el nombre del sistema operativo instalado en una partición
1760//      Parámetros:
1761//              disco:  Disco  1,2,3..
1762//              particion:      Número de la partición 
1763//      Devuelve:
1764//              Una cadena con el nombre del S.O.
1765// ________________________________________________________________________________________________________
1766char* TomaNomSO(char*disco,int particion)
1767{
1768        int herror,lon;
1769        char *infosopar;
1770        char* sover[2];
1771        char ch[2];
1772       
1773        infosopar=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDA); // Información del S.O. de la partición
1774       
1775        sprintf(cmdshell,"%s/getOsVersion",HIDRASCRIPTS);       
1776        sprintf(parametros," %s %s %d","getOsVersion",disco,particion);
1777        herror=EjecutarScript(cmdshell,parametros,infosopar,true);
1778                if(herror){
1779            UltimoErrorScript(herror,"TomaNomSO()");     // Se ha producido algún error
1780                return(NULL);
1781    }
1782    if(strlen(infosopar)==0) return(NULL); // NO Existe S.O. en la partición
1783    strcpy(ch,":");// caracter delimitador (dos puntos)
1784        lon=SplitParametros(sover,infosopar,ch);
1785        return(sover[1]);
1786}
1787//______________________________________________________________________________________________________
1788// Función: MuestraMenu
1789//
1790//      Descripción:
1791//              Muestra menú del cliente
1792//      Parámetros:
1793//              ips: Dirección IP del servidor web  que implementa la consola de adminsitración
1794//        urp: Path o url de la página web que muestra el menu del cliente
1795//              iph:    Dirección ip del cliente       
1796//      Devuelve:
1797//              Nada
1798// ________________________________________________________________________________________________________
1799int MuestraMenu(char*ips,char *urp,char *iph)
1800{
1801        pid_t  pid;
1802        int herror,nargs,resul;
1803
1804
1805        sprintf(cmdshell,"%s/menuBrowser",HIDRASCRIPTS);
1806        sprintf(parametros,"%s %s %s %s","menuBrowser",ips,urp,iph);   
1807        nargs=SplitParametros(argumentos,parametros," "); // Crea matriz de los argumentos del scripts
1808        if((pid=fork())==0){
1809                /* Proceso hijo que ejecuta el script */
1810                execv(cmdshell,argumentos);
1811                //resul=execlp (script, script, argumentos[0],argumentos[1],NULL);   
1812                exit(resul);   
1813        }
1814        else {
1815                if (pid ==-1){
1816                        UltimoErrorScript(herror,"MuestraMenu()");      // Se ha producido algún error
1817                        return(false); 
1818                }               
1819        }
1820        return(true);
1821}
1822//______________________________________________________________________________________________________
1823// Función: InventarioHardware
1824//
1825//      Descripción:
1826//              Recupera la configuración de hardware del ordenador
1827//      Parámetros:
1828//              - trama: Trama recibida con las especificaciones del comando
1829//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1830//      Devuelve:
1831//              true si el proceso fue correcto o false en caso contrario
1832//      Especificaciones:
1833//              Lo que se envía al servidor es una cadena con el formato de salida del script que ejecuta
1834//              está función. (Vease scripts hidraHardwareInfo)
1835// ________________________________________________________________________________________________________
1836int InventarioHardware(TRAMA *trama,TRAMA *nwtrama)
1837{
1838        int herror,res;
1839        char *parametroshrd;
1840       
1841        parametroshrd=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDALARGA);
1842        sprintf(cmdshell,"%s/listHardwareInfo",HIDRASCRIPTS);
1843        herror=EjecutarScript(cmdshell,NULL,parametroshrd,false);
1844        if(herror){
1845            UltimoErrorScript(herror,"InventarioHardware()");   // Se ha producido algún error
1846    }
1847    res=(herror==0); // Si se ha producido algún error el resultado de la ejecución de error
1848
1849        int lon;
1850        lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_TomaHardware\r");               
1851        lon+=sprintf(nwtrama->parametros+lon,"hrd=%s\r",parametroshrd);
1852        RespuestaEjecucionComando(trama,nwtrama,res);   
1853        return(res);
1854}
1855//______________________________________________________________________________________________________
1856// Función: InventarioSoftware
1857//
1858//      Descripción:
1859//              Recupera la configuración de software del ordenador
1860//      Parámetros:
1861//              - trama: Trama recibida con las especificaciones del comando
1862//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1863//      Devuelve:
1864//              true si el proceso fue correcto o false en caso contrario
1865//      Especificaciones:
1866//              Lo que se envía al servidor es una cadena con el formato de salida del script que ejecuta
1867//              está función. (Vease scripts hidraSoftwareInfo)
1868// ________________________________________________________________________________________________________
1869int InventarioSoftware(TRAMA *trama,TRAMA *nwtrama)
1870{
1871        int herror,res;
1872        char *parametrossft,*infopar;
1873        char *particion=TomaParametro("par",trama->parametros); // Toma partición
1874
1875        char *disco=(char*)ReservaMemoria(2);
1876        sprintf(disco,"1"); // Siempre el disco 1
1877
1878        sprintf(cmdshell,"%s/listSoftwareInfo",HIDRASCRIPTS);
1879        sprintf(parametros,"%s %s %s","listSoftwareInfo",disco,particion);
1880
1881        parametrossft=(char*)ReservaMemoria(LONGITUD_SCRIPTSALIDALARGA);
1882        herror=EjecutarScript(cmdshell,parametros,parametrossft,false);
1883        if(herror){
1884            UltimoErrorScript(herror,"InventarioSoftware()");   // Se ha producido algún error
1885    }
1886    res=(herror==0); // Si se ha producido algún error el resultado de la ejecución de error
1887        // Toma tipo de partición
1888                infopar=(char*)ReservaMemoria(16); //Tipo de partición
1889                if(res && infopar){
1890                                sprintf(cmdshell,"%s/getFsType",HIDRASCRIPTS); 
1891                                sprintf(parametros," %s %s %s","getFsType",disco,particion);
1892                                herror=EjecutarScript(cmdshell,parametros,infopar,true);
1893                                if(herror){
1894                        UltimoErrorScript(herror,"InventarioSoftware()");        // Se ha producido algún error
1895          }
1896        }
1897  int lon;
1898        lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_TomaSoftware\r");               
1899        lon+=sprintf(nwtrama->parametros+lon,"sft=%s\r",parametrossft);
1900        lon+=sprintf(nwtrama->parametros+lon,"par=%s\r",particion);     
1901        lon+=sprintf(nwtrama->parametros+lon,"tfs=%s\r",infopar);       
1902        RespuestaEjecucionComando(trama,nwtrama,res);   
1903        return(res);
1904}
1905//______________________________________________________________________________________________________
1906// Función: TomaConfiguracion
1907//
1908//      Descripción:
1909//              Toma la configuración de particiones de un ordenador
1910//      Parámetros:
1911//              - trama: Trama recibida con las especificaciones del comando
1912//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1913//      Devuelve:
1914//              true si el proceso fue correcto o false en caso contrario
1915// ________________________________________________________________________________________________________
1916int TomaConfiguracion(TRAMA *trama,TRAMA *nwtrama)
1917{       
1918                char* parametroscfg;
1919               
1920                char *disco=(char*)ReservaMemoria(2);
1921                sprintf(disco,"1"); // Siempre el disco 1
1922
1923                parametroscfg=LeeConfiguracion(disco);
1924               
1925                int lon;                       
1926                lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_TomaConfiguracion\r");   
1927                lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg);         
1928                RespuestaEjecucionComando(trama,nwtrama,true); 
1929               
1930                return(true);
1931}
1932//______________________________________________________________________________________________________
1933// Función: ExecShell
1934//
1935//      Descripción:
1936//              Ejecuta un script de la Shell
1937//      Parámetros:
1938//              - trama: Trama recibida con las especificaciones del comando
1939//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
1940//      Devuelve:
1941//              true si el proceso fue correcto o false en caso contrario
1942// ________________________________________________________________________________________________________
1943int ExecShell(TRAMA *trama,TRAMA *nwtrama)
1944{
1945        FILE* f;
1946        long lSize;
1947        int herror,res;
1948
1949        char* wscript=TomaParametro("scp",trama->parametros);   // Código del script   
1950        char* codigo=URLDecode(wscript);        // Decodifica el código recibido con formato URLCode
1951       
1952        sprintf(filecmdshell,"%s/%s","/tmp","_hidrascript_");
1953        f = fopen(filecmdshell,"wt");   // Abre fichero de script
1954        if(f==NULL)
1955                res=false; // Error de apertura del fichero de configuración
1956        else{
1957                lSize=strlen(codigo);
1958                fwrite(codigo,1,lSize,f);       // Escribe el código a ejecutar
1959                fclose(f);
1960               
1961                sprintf(cmdshell,"/bin/chmod"); // Da permiso de ejecución al fichero
1962                sprintf(parametros," %s %s %s","/bin/chmod","+x",filecmdshell);
1963               
1964                herror=EjecutarScript(cmdshell,parametros,NULL,true);
1965                if(herror){
1966                        UltimoErrorScript(herror,"ExecShell()");        // Se ha producido algún error
1967                        res=false;     
1968                }
1969                else{
1970                        sprintf(cmdshell,"%s",filecmdshell);    // Ejecución el fichero de script creado
1971                        //int herror=EjecutarScript(cmdshell,NULL,NULL,true);
1972                        int herror=system(cmdshell);
1973                        if(herror){
1974                                UltimoErrorScript(herror,"ExecShell()");        // Se ha producido algún error
1975                                res=false;     
1976                        }               
1977                }
1978        }
1979       
1980        char *disco=(char*)ReservaMemoria(2);
1981        sprintf(disco,"1"); // Siempre el disco 1
1982        char* parametroscfg=LeeConfiguracion(disco);
1983        int lon;                       
1984       
1985        lon=sprintf(nwtrama->parametros,"nfn=RESPUESTA_ExecShell\r");   
1986        lon+=sprintf(nwtrama->parametros+lon,"cfg=%s\r",parametroscfg);
1987        RespuestaEjecucionComando(trama,nwtrama,res);   
1988               
1989        return(res);
1990}
1991//______________________________________________________________________________________________________
1992// Función: URLDecode
1993//
1994//      Descripción:
1995//              Decodifica una cadena codificada con UrlEncode
1996//      Parámetros:
1997//              - src: La cadena a decodificar
1998//      Devuelve:
1999//              La cadena decodificada
2000// ________________________________________________________________________________________________________
2001char* URLDecode(char *src)
2002{
2003        const char *p = src;
2004        char code[3] = {0};
2005        unsigned long ascii = 0;       
2006        char *end = NULL;
2007        char *dest,*cad;
2008
2009        dest=(char*)ReservaMemoria(strlen(src));        // Reserva buffer  para la cadena                       
2010        cad=dest;
2011        while(*p){
2012                if(*p == '%'){
2013                        memcpy(code, ++p, 2);
2014                        ascii = strtoul(code, &end, 16);
2015                        *dest++ = (char)ascii;
2016                        p += 2;
2017                }
2018                else
2019                        *dest++ = *p++;
2020        }
2021        return(cad);   
2022}
2023//______________________________________________________________________________________________________
2024// Función: RespuestaEjecucionComando
2025//
2026//      Descripción:
2027//              Envia una respuesta a una ejecucion de comando al servidor de Administración
2028//      Parámetros:
2029//              - trama: Trama recibida con las especificaciones del comando
2030//              - nwtrama: Nueva trama a enviar al servidor con la respuesta de la acción, si ésta procede
2031//              -  res: Resultado de la ejecución (true si la ejecución es correcta y false en caso contrario) 
2032//      Devuelve:
2033//              true si la respuesta se envía correctamente al servidor
2034// ________________________________________________________________________________________________________
2035int RespuestaEjecucionComando(TRAMA* trama, TRAMA *nwtrama, int res)
2036{
2037                int idsuceso=0;
2038                char *widsuceso=TomaParametro("ids",trama->parametros);
2039                if(widsuceso) idsuceso=atoi(widsuceso);
2040                int lon;
2041                lon=strlen(nwtrama->parametros);
2042                lon+=sprintf(nwtrama->parametros+lon,"ids=%d\r",idsuceso);      //  Identificador del suceso
2043                char descrierror[250];
2044                if (res){ // Resultado satisfactorio
2045                        lon+=sprintf(nwtrama->parametros+lon,"res=%s\r","1");   // Resultado de la ejecucin del comando
2046                        sprintf(descrierror,"%s "," ");
2047                        lon+=sprintf(nwtrama->parametros+lon,"der=%s\r",descrierror);   // Dscripcin del error si lo ha habido
2048                }       
2049                else{ // Algún error
2050                        lon+=sprintf(nwtrama->parametros+lon,"res=%s\r","2");   // Resultado de la ejecución del comando               
2051                        sprintf(descrierror,"Error.-(%s) en modulo %s",e.msg,e.modulo);
2052                        lon+=sprintf(nwtrama->parametros+lon,"der=%s\r",descrierror);   // Descripción del error si lo ha habido
2053                }
2054                if(AbreConexionTCP()){
2055                        if(!EnviaTramasHidra(sock,nwtrama)){
2056                                UltimoError(21,"RespuestaEjecucionComando()");
2057                                return(false);
2058                        }
2059                        if(!RecibeTramasHidra(sock,trama)){
2060                                UltimoError(22,"RespuestaEjecucionComando()");
2061                                return(false); 
2062                        }               
2063                        CierraConexionTCP();
2064                        GestionTramas(trama);   // Analiza la trama
2065                }
2066                else{
2067                        UltimoError(2,"RespuestaEjecucionComando()");   
2068                        return(false);                 
2069                }
2070                return(true);
2071}
2072
2073//***********************************************************************************************************************
2074// PROGRAMA PRINCIPAL
2075//***********************************************************************************************************************
2076int  main(int argc, char *argv[])
2077{
2078        //Archivos por defecto
2079        strcpy(szPathFileCfg,"ogAdmClient.cfg");
2080        strcpy(szPathFileLog,"ogAdmClient.log");
2081
2082        // Validación de argumentos y lectura del fichero de configuración
2083        if(!ValidacionParametros(argc,argv))
2084                exit(EXIT_FAILURE);
2085        else{   
2086                if(!CrearArchivoLog(szPathFileLog))
2087                        exit(EXIT_FAILURE);
2088                else
2089                        if(!LeeFileConfiguracion(szPathFileCfg)){ // Toma parámetros de configuracion
2090                                UltimoError(13,"Main()");       
2091                                exit(EXIT_FAILURE);
2092                        }
2093        }
2094        // Guarda datos básicos del cliente     
2095        strcpy(Propiedades.servidorhidra,Servidorhidra);       
2096        strcpy(Propiedades.puerto,Puerto);     
2097        strcpy(Propiedades.idordenador,"0");
2098        if(!TomaIPlocal()){ // Error al recuperar la IP local   
2099                UltimoError(0,"Main()");       
2100                exit(EXIT_FAILURE);
2101        }
2102        strcpy(Propiedades.IPlocal,IPlocal);   
2103
2104        Log("Abriendo sesión en el servidor de Administración");               
2105        if(InclusionCliente()){ // El cliente ha abierto sesión correctamente
2106                if(strcmp(Propiedades.idordenador,"0")==0){     // Ha habido algún problema al inciar sesión
2107                        UltimoError(0,"Main()");       
2108                        exit(EXIT_FAILURE);
2109                }
2110                Log("Cliente iniciado");               
2111                Log("Ejecución de archivo Autoexec");
2112                if(!AutoexecClienteHidra()){  // Ejecución fichero autoexec     
2113                        UltimoError(0,"Main()");       
2114                        exit(EXIT_FAILURE);
2115                }                               
2116                Log("Procesa comandos pendientes");
2117                ComandosPendientes(); // Bucle para procesar comandos pendientes
2118                Log("Acciones pendientes procesadas");
2119                //MuestraMenu(Servidorhidra,URLMENU,Propiedades.IPlocal);
2120                Log("Disponibilidad para comandos interactivos activada ...");
2121                ProcesaComandos(); // Bucle para procesar comando       s interactivos
2122                Log("Disponibilidad para comandos interactivos desactivada...");
2123        }
2124        else{
2125                UltimoError(0,"Main()");       
2126                exit(EXIT_FAILURE);
2127        }
2128        exit(0);
2129}
2130
2131       
2132
2133
Note: See TracBrowser for help on using the repository browser.