source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ d81fc6a

Last change on this file since d81fc6a was de687e3, checked in by ramon <ramongomez@…>, 10 years ago

#673: Integrar código de la versión 1.0.6 en rama principal.

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

  • Property mode set to 100644
File size: 126.5 KB
Line 
1// *******************************************************************************************************
2// Servicio: ogAdmServer
3// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
4// Fecha Creación: Marzo-2010
5// Fecha Última modificación: Marzo-2010
6// Nombre del fichero: ogAdmServer.cpp
7// Descripción :Este fichero implementa el servicio de administración general del sistema
8// *******************************************************************************************************
9#include "ogAdmServer.h"
10#include "ogAdmLib.c"
11//________________________________________________________________________________________________________
12//      Función: tomaConfiguracion
13//
14//      Descripción:
15//              Lee el fichero de configuración del servicio
16//      Parámetros:
17//              filecfg : Ruta completa al fichero de configuración
18//      Devuelve:
19//              TRUE: Si el proceso es correcto
20//              FALSE: En caso de ocurrir algún error
21//________________________________________________________________________________________________________
22BOOLEAN tomaConfiguracion(char* filecfg) {
23        char modulo[] = "tomaConfiguracion()";
24
25        if (filecfg == NULL || strlen(filecfg) == 0) {
26                errorLog(modulo, 1, FALSE); // Fichero de configuración del servicio vacío
27                return (FALSE);
28        }
29        FILE *fcfg;
30        long lSize;
31        char * buffer, *lineas[MAXPRM], *dualparametro[2];
32        int i, numlin, resul;
33
34        fcfg = fopen(filecfg, "rt");
35        if (fcfg == NULL) {
36                errorLog(modulo, 2, FALSE); // No existe fichero de configuración del servicio
37                return (FALSE);
38        }
39
40        fseek(fcfg, 0, SEEK_END);
41        lSize = ftell(fcfg); // Obtiene tamaño del fichero.
42        rewind(fcfg);
43        buffer = (char*) reservaMemoria(lSize + 1); // Toma memoria para el buffer de lectura.
44        if (buffer == NULL) { // No hay memoria suficiente para el buffer
45                errorLog(modulo, 3, FALSE);
46                return (FALSE);
47        }
48        fread(buffer, 1, lSize, fcfg); // Lee contenido del fichero
49        buffer[lSize] = (char) NULL;
50        fclose(fcfg);
51
52        servidoradm[0] = (char) NULL; //inicializar variables globales
53        usuario[0] = (char) NULL;
54        pasguor[0] = (char) NULL;
55        datasource[0] = (char) NULL;
56        catalog[0] = (char) NULL;
57        aulaup[0] = (char) NULL;
58
59        numlin = splitCadena(lineas, buffer, '\n');
60        for (i = 0; i < numlin; i++) {
61                splitCadena(dualparametro, lineas[i], '=');
62                resul = strcmp(StrToUpper(dualparametro[0]), "SERVIDORADM");
63                if (resul == 0)
64                        strcpy(servidoradm, dualparametro[1]);
65                resul = strcmp(StrToUpper(dualparametro[0]), "PUERTO");
66                if (resul == 0)
67                        strcpy(puerto, dualparametro[1]);
68                resul = strcmp(StrToUpper(dualparametro[0]), "USUARIO");
69                if (resul == 0)
70                        strcpy(usuario, dualparametro[1]);
71                resul = strcmp(StrToUpper(dualparametro[0]), "PASSWORD");
72                if (resul == 0)
73                        strcpy(pasguor, dualparametro[1]);
74                resul = strcmp(StrToUpper(dualparametro[0]), "DATASOURCE");
75                if (resul == 0)
76                        strcpy(datasource, dualparametro[1]);
77                resul = strcmp(StrToUpper(dualparametro[0]), "CATALOG");
78                if (resul == 0)
79                        strcpy(catalog, dualparametro[1]);
80                resul = strcmp(StrToUpper(dualparametro[0]), "AULAUP");
81                if (resul == 0)
82                        strcpy(catalog, dualparametro[1]);
83        }
84        if (servidoradm[0] == (char) NULL) {
85                liberaMemoria(buffer);
86                errorLog(modulo, 4, FALSE); // Falta parámetro SERVIDORADM
87                return (FALSE);
88        }
89        if (puerto[0] == (char) NULL) {
90                liberaMemoria(buffer);
91                errorLog(modulo, 5, FALSE); // Falta parámetro PUERTO
92                return (FALSE);
93        }
94        if (usuario[0] == (char) NULL) {
95                liberaMemoria(buffer);
96                errorLog(modulo, 6, FALSE); // Falta parámetro USUARIO
97                return (FALSE);
98        }
99        if (pasguor[0] == (char) NULL) {
100                liberaMemoria(buffer);
101                errorLog(modulo, 7, FALSE); // Falta parámetro PASSWORD
102                return (FALSE);
103        }
104        if (datasource[0] == (char) NULL) {
105                liberaMemoria(buffer);
106                errorLog(modulo, 8, FALSE); // Falta parámetro DATASOURCE
107                return (FALSE);
108        }
109        if (catalog[0] == (char) NULL) {
110                liberaMemoria(buffer);
111                errorLog(modulo, 9, FALSE); // Falta parámetro CATALOG
112                return (FALSE);
113        }
114        if (aulaup[0] == (char) NULL) {
115                strcpy(aulaup, "0"); // Por defecto el conmutador de registro automático esta en off
116
117        }
118        liberaMemoria(buffer);
119        return (TRUE);
120}
121// ________________________________________________________________________________________________________
122// Función: gestionaTrama
123//
124//              Descripción:
125//                      Procesa las tramas recibidas .
126//              Parametros:
127//                      - s : Socket usado para comunicaciones
128//      Devuelve:
129//              TRUE: Si el proceso es correcto
130//              FALSE: En caso de ocurrir algún error
131// ________________________________________________________________________________________________________
132BOOLEAN gestionaTrama(SOCKET *socket_c)
133{
134        TRAMA* ptrTrama;
135        int i, res;
136        char *nfn;
137        char modulo[] = "gestionaTrama()";
138
139        ptrTrama=recibeTrama(socket_c);
140       
141        if (ptrTrama){
142                INTROaFINCAD(ptrTrama);
143                nfn = copiaParametro("nfn",ptrTrama); // Toma nombre de la función
144
145                for (i = 0; i < MAXIMAS_FUNCIONES; i++) { // Recorre funciones que procesan las tramas
146                        res = strcmp(tbfuncionesServer[i].nf, nfn);
147                        if (res == 0) { // Encontrada la función que procesa el mensaje
148                                liberaMemoria(nfn);
149                                res=tbfuncionesServer[i].fptr(socket_c, ptrTrama); // Invoca la función
150                                liberaMemoria((char*)ptrTrama);
151                                return(res);
152                        }
153                }
154               
155                /*
156                 Sólo puede ser un comando personalizado o su notificación
157                if (ptrTrama->tipo == MSG_COMANDO)
158                        return (Comando(socket_c, ptrTrama));
159                else {
160                        if (ptrTrama->tipo == MSG_NOTIFICACION)
161                                return (RESPUESTA_Comando(socket_c, ptrTrama));
162                        else
163                                errorLog(modulo, 18, FALSE); // No se reconoce el mensaje
164                }
165                */
166        }
167        else
168                errorLog(modulo, 17, FALSE); // Error en la recepción
169        return (TRUE);
170}
171// ________________________________________________________________________________________________________
172// Función: Sondeo
173//
174//      Descripción:
175//              Solicita a los clientes su disponibiliad para recibir comandos interactivos
176//      Parámetros:
177//              - socket_c: Socket del cliente que envió el mensaje
178//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
179//      Devuelve:
180//              TRUE: Si el proceso es correcto
181//              FALSE: En caso de ocurrir algún error
182// ________________________________________________________________________________________________________
183BOOLEAN Sondeo(SOCKET *socket_c, TRAMA* ptrTrama) {
184        char msglog[LONSTD];
185        char modulo[] = "Sondeo()";
186
187        if (!enviaComando(ptrTrama, CLIENTE_APAGADO)) {
188                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
189                errorInfo(modulo, msglog);
190                respuestaConsola(socket_c, ptrTrama, FALSE);
191                return (FALSE);
192        }
193        respuestaConsola(socket_c, ptrTrama, TRUE);
194        return (TRUE);
195}
196// ________________________________________________________________________________________________________
197// Función: respuestaSondeo
198//
199//      Descripción:
200//              Recupera el estatus de los ordenadores solicitados leyendo la tabla de sockets
201//      Parámetros:
202//              - socket_c: Socket del cliente que envió el mensaje
203//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
204//      Devuelve:
205//              TRUE: Si el proceso es correcto
206//              FALSE: En caso de ocurrir algún error
207// ________________________________________________________________________________________________________
208BOOLEAN respuestaSondeo(SOCKET *socket_c, TRAMA* ptrTrama) {
209        int i;
210        long lSize;
211        char *iph, *Ipes;
212        char modulo[] = "respuestaSondeo()";
213
214        iph = copiaParametro("iph",ptrTrama); // Toma dirección/es IP
215        lSize = strlen(iph); // Calcula longitud de la cadena de direccion/es IPE/S
216        Ipes = (char*) reservaMemoria(lSize + 1);
217        if (Ipes == NULL) {
218                errorLog(modulo, 3, FALSE);
219                return (FALSE);
220        }
221        strcpy(Ipes, iph); // Copia cadena de IPES
222        liberaMemoria(iph);
223        initParametros(ptrTrama,0);
224        strcpy(ptrTrama->parametros, "tso="); // Compone retorno tso (sistemas operativos de los clientes )
225        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
226                if (strncmp(tbsockets[i].ip, "\0", 1) != 0) { // Si es un cliente activo
227                        if (contieneIP(Ipes, tbsockets[i].ip)) { // Si existe la IP en la cadena
228                                strcat(ptrTrama->parametros, tbsockets[i].ip); // Compone retorno
229                                strcat(ptrTrama->parametros, "/"); // "ip/sistema operativo;"
230                                strcat(ptrTrama->parametros, tbsockets[i].estado);
231                                strcat(ptrTrama->parametros, ";");
232                        }
233                }
234        }
235        strcat(ptrTrama->parametros, "\r");
236        liberaMemoria(Ipes);
237        if (!mandaTrama(socket_c, ptrTrama)) {
238                errorLog(modulo, 26, FALSE);
239                return (FALSE);
240        }
241        return (TRUE);
242}
243// ________________________________________________________________________________________________________
244// Función: Actualizar
245//
246//      Descripción:
247//              Obliga a los clientes a iniciar sesión en el sistema
248//      Parámetros:
249//              - socket_c: Socket del cliente que envió el mensaje
250//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
251//      Devuelve:
252//              TRUE: Si el proceso es correcto
253//              FALSE: En caso de ocurrir algún error
254// ________________________________________________________________________________________________________
255BOOLEAN Actualizar(SOCKET *socket_c, TRAMA* ptrTrama) {
256        char msglog[LONSTD];
257        char modulo[] = "Actualizar()";
258
259        if (!enviaComando(ptrTrama, CLIENTE_APAGADO)) {
260                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
261                errorInfo(modulo, msglog);
262                return (FALSE);
263        }
264        respuestaConsola(socket_c, ptrTrama, TRUE);
265        return (TRUE);
266}
267// ________________________________________________________________________________________________________
268// Función: Purgar
269//
270//      Descripción:
271//              Detiene la ejecución del browser en el cliente
272//      Parámetros:
273//              - socket_c: Socket del cliente que envió el mensaje
274//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
275//      Devuelve:
276//              TRUE: Si el proceso es correcto
277//              FALSE: En caso de ocurrir algún error
278// ________________________________________________________________________________________________________
279BOOLEAN Purgar(SOCKET *socket_c, TRAMA* ptrTrama) {
280        char msglog[LONSTD];
281        char modulo[] = "Purgar()";
282
283        if (!enviaComando(ptrTrama, CLIENTE_APAGADO)) {
284                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
285                errorInfo(modulo, msglog);
286                return (FALSE);
287        }
288        respuestaConsola(socket_c, ptrTrama, TRUE);
289        return (TRUE);
290}
291// ________________________________________________________________________________________________________
292// Función: ConsolaRemota
293//
294//      Descripción:
295//              Envia un script al cliente, éste lo ejecuta y manda el archivo que genera la salida por pantalla
296//      Parámetros:
297//              - socket_c: Socket del cliente que envió el mensaje
298//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
299//      Devuelve:
300//              TRUE: Si el proceso es correcto
301//              FALSE: En caso de ocurrir algún error
302// ________________________________________________________________________________________________________
303BOOLEAN ConsolaRemota(SOCKET *socket_c, TRAMA* ptrTrama)
304{
305        char *iph,fileco[LONPRM],msglog[LONSTD],*ptrIpes[MAXIMOS_CLIENTES];;
306        FILE* f;
307        int i,lon;
308        char modulo[] = "ConsolaRemota()";
309
310        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
311                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
312                errorInfo(modulo, msglog);
313                respuestaConsola(socket_c, ptrTrama, FALSE);
314                return (FALSE);
315        }
316        INTROaFINCAD(ptrTrama);
317        /* Destruye contenido del fichero de eco anterior */
318        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip del cliente
319        lon = splitCadena(ptrIpes,iph,';');
320        for (i = 0; i < lon; i++) {
321                sprintf(fileco,"/tmp/_Seconsola_%s",ptrIpes[i]); // Nombre que tendra el archivo en el Servidor
322                f = fopen(fileco, "wt");
323                fclose(f);
324        }
325        liberaMemoria(iph);
326        respuestaConsola(socket_c, ptrTrama, TRUE);
327        return (TRUE);
328}
329// ________________________________________________________________________________________________________
330// Función: EcoConsola
331//
332//      Descripción:
333//              Solicita el eco de una consola remota almacenado en un archivo de eco
334//      Parámetros:
335//              - socket_c: Socket del cliente que envió el mensaje
336//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros del mensaje
337//      Devuelve:
338//              TRUE: Si el proceso es correcto
339//              FALSE: En caso de ocurrir algún error
340// ________________________________________________________________________________________________________
341BOOLEAN EcoConsola(SOCKET *socket_c, TRAMA* ptrTrama)
342{
343        char *iph,fileco[LONPRM],*buffer;
344        int lSize;
345        char modulo[] = "EcoConsola()";
346
347        INTROaFINCAD(ptrTrama);
348        // Lee archivo de eco de consola
349        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip del cliente
350        sprintf(fileco,"/tmp/_Seconsola_%s",iph); // Nombre del archivo en el Servidor
351        lSize=lonArchivo(fileco);
352        if(lSize>0){ // Si el fichero tiene contenido...
353                initParametros(ptrTrama,lSize+LONGITUD_PARAMETROS);
354                buffer=leeArchivo(fileco);
355                sprintf(ptrTrama->parametros,"res=%s\r",buffer);
356                liberaMemoria(buffer);
357        }
358        else{
359                initParametros(ptrTrama,0);
360                sprintf(ptrTrama->parametros,"res=\r");
361        }
362        ptrTrama->tipo=MSG_RESPUESTA; // Tipo de mensaje
363        if (!mandaTrama(socket_c, ptrTrama)) {
364                errorLog(modulo, 26, FALSE);
365                return (FALSE);
366        }
367        return (TRUE);
368}
369// ________________________________________________________________________________________________________
370// Función: clienteDisponible
371//
372//      Descripción:
373//              Comprueba la disponibilidad del cliente para recibir comandos interactivos
374//      Parametros:
375//              - ip : La ip del cliente a buscar
376//              - idx: (Salida)  Indice que ocupa el cliente, de estar ya registrado
377//      Devuelve:
378//              TRUE: Si el cliente está disponible
379//              FALSE: En caso contrario
380// ________________________________________________________________________________________________________
381BOOLEAN clienteDisponible(char *ip, int* idx) {
382        int estado;
383
384        if (clienteExistente(ip, idx)) {
385                estado = strcmp(tbsockets[*idx].estado, CLIENTE_OCUPADO); // Cliente ocupado
386                if (estado == 0)
387                        return (FALSE);
388
389                estado = strcmp(tbsockets[*idx].estado, CLIENTE_APAGADO); // Cliente apagado
390                if (estado == 0)
391                        return (FALSE);
392
393                estado = strcmp(tbsockets[*idx].estado, CLIENTE_INICIANDO); // Cliente en proceso de inclusión
394                if (estado == 0)
395                        return (FALSE);
396
397                return (TRUE); // En caso contrario el cliente está disponible
398        }
399        return (FALSE); // Cliente no está registrado en el sistema
400}
401// ________________________________________________________________________________________________________
402// Función: clienteExistente
403//
404//      Descripción:
405//              Comprueba si el cliente está registrado en la tabla de socket del sistema
406//      Parametros:
407//              - ip : La ip del cliente a buscar
408//              - idx:(Salida)  Indice que ocupa el cliente, de estar ya registrado
409//      Devuelve:
410//              TRUE: Si el cliente está registrado
411//              FALSE: En caso contrario
412// ________________________________________________________________________________________________________
413BOOLEAN clienteExistente(char *ip, int* idx) {
414        int i;
415        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
416                if (contieneIP(ip, tbsockets[i].ip)) { // Si existe la IP en la cadena
417                        *idx = i;
418                        return (TRUE);
419                }
420        }
421        return (FALSE);
422}
423// ________________________________________________________________________________________________________
424// Función: hayHueco
425//
426//      Descripción:
427//              Esta función devuelve TRUE o FALSE dependiendo de que haya hueco en la tabla de sockets para un nuevo cliente.
428//      Parametros:
429//              - idx:   Primer indice libre que se podrn utilizar
430//      Devuelve:
431//              TRUE: Si el proceso es correcto
432//              FALSE: En caso de ocurrir algún error
433// ________________________________________________________________________________________________________
434BOOLEAN hayHueco(int *idx) {
435        int i;
436
437        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
438                if (strncmp(tbsockets[i].ip, "\0", 1) == 0) { // Hay un hueco
439                        *idx = i;
440                        return (TRUE);
441                }
442        }
443        return (FALSE);
444}
445// ________________________________________________________________________________________________________
446// Función: InclusionClienteWin
447//
448//      Descripción:
449//              Esta función incorpora el socket de un nuevo cliente Windows o Linux a la tabla de clientes
450//      Parámetros:
451//              - socket_c: Socket del cliente que envió el mensaje
452//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
453//      Devuelve:
454//              TRUE: Si el proceso es correcto
455//              FALSE: En caso de ocurrir algún error
456// ________________________________________________________________________________________________________
457BOOLEAN InclusionClienteWinLnx(SOCKET *socket_c, TRAMA *ptrTrama)
458 {
459        char modulo[] = "InclusionClienteWinLnx()";
460        int res,idordenador,lon;
461        char nombreordenador[LONFIL];
462               
463        res=procesoInclusionClienteWinLnx(socket_c, ptrTrama,&idordenador,nombreordenador);
464       
465        // Prepara la trama de respuesta
466
467        initParametros(ptrTrama,0);
468        ptrTrama->tipo=MSG_RESPUESTA;
469        lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_InclusionClienteWinLnx\r");
470        lon += sprintf(ptrTrama->parametros + lon, "ido=%d\r", idordenador);
471        lon += sprintf(ptrTrama->parametros + lon, "npc=%s\r", nombreordenador);       
472        lon += sprintf(ptrTrama->parametros + lon, "res=%d\r", res);   
473       
474        if (!mandaTrama(socket_c, ptrTrama)) {
475                errorLog(modulo, 26, FALSE);
476                return (FALSE);
477        }
478        return (TRUE); 
479}
480// ________________________________________________________________________________________________________
481// Función: procesoInclusionClienteWinLnx
482//
483//      Descripción:
484//              Implementa el proceso de inclusión en el sistema del Cliente Windows o Linux
485//      Parámetros de entrada:
486//              - socket_c: Socket del cliente que envió el mensaje
487//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
488//      Parámetros de salida:
489//              - ido: Identificador del ordenador
490//              - nombreordenador: Nombre del ordenador
491//      Devuelve:
492//              Código del error producido en caso de ocurrir algún error, 0 si el proceso es correcto
493// ________________________________________________________________________________________________________
494BOOLEAN procesoInclusionClienteWinLnx(SOCKET *socket_c, TRAMA *ptrTrama,int *idordenador,char* nombreordenador)
495 {
496        char msglog[LONSTD], sqlstr[LONSQL];
497        Database db;
498        Table tbl;
499
500        char *iph;
501        char modulo[] = "procesoInclusionClienteWinLnx()";
502       
503        // Toma parámetros
504        iph = copiaParametro("iph",ptrTrama); // Toma ip
505
506        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexión con la BD
507                errorLog(modulo, 20, FALSE);
508                db.GetErrorErrStr(msglog);
509                errorInfo(modulo, msglog);
510                return (20);
511        }
512
513        // Recupera los datos del cliente
514        sprintf(sqlstr,
515                        "SELECT idordenador,nombreordenador FROM ordenadores "
516                                " WHERE ordenadores.ip = '%s'", iph);
517
518        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
519                errorLog(modulo, 21, FALSE);
520                db.GetErrorErrStr(msglog);
521                errorInfo(modulo, msglog);
522                return (21);
523        }
524
525        if (tbl.ISEOF()) { // Si no existe el cliente
526                errorLog(modulo, 22, FALSE);
527                return (22);
528        }
529
530        if (ndebug == DEBUG_ALTO) {
531                sprintf(msglog, "%s IP:%s", tbMensajes[2], iph);
532                infoDebug(msglog);
533        }
534        if (!tbl.Get("idordenador", *idordenador)) {
535                tbl.GetErrorErrStr(msglog);
536                errorInfo(modulo, msglog);
537                return (FALSE);
538        }
539        if (!tbl.Get("nombreordenador", nombreordenador)) {
540                tbl.GetErrorErrStr(msglog);
541                errorInfo(modulo, msglog);
542                return (FALSE);
543        }
544        db.Close();
545       
546        if (!registraCliente(iph)) { // Incluyendo al cliente en la tabla de sokets
547                liberaMemoria(iph);
548                errorLog(modulo, 25, FALSE);
549                return (25);
550        }
551        liberaMemoria(iph);
552        return(0);
553}
554// ________________________________________________________________________________________________________
555// Función: InclusionCliente
556//
557//      Descripción:
558//              Esta función incorpora el socket de un nuevo cliente a la tabla de clientes y le devuelve alguna de sus propiedades:
559//              nombre, identificador, tamaño de la caché , etc ...
560//      Parámetros:
561//              - socket_c: Socket del cliente que envió el mensaje
562//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
563//      Devuelve:
564//              TRUE: Si el proceso es correcto
565//              FALSE: En caso de ocurrir algún error
566// ________________________________________________________________________________________________________
567BOOLEAN InclusionCliente(SOCKET *socket_c, TRAMA *ptrTrama) {
568        char modulo[] = "InclusionCliente()";
569
570        if (!procesoInclusionCliente(socket_c, ptrTrama)) { // Ha habido algún error...
571                initParametros(ptrTrama,0);
572                strcpy(ptrTrama->parametros, "nfn=RESPUESTA_InclusionCliente\rres=0\r");
573                if (!mandaTrama(socket_c, ptrTrama)) {
574                        errorLog(modulo, 26, FALSE);
575                        return (FALSE);
576                }
577        }
578        return (TRUE);
579}       
580// ________________________________________________________________________________________________________
581// Función: procesoInclusionCliente
582//
583//      Descripción:
584//              Implementa el proceso de inclusión en el sistema del Cliente
585//      Parámetros:
586//              - socket_c: Socket del cliente que envió el mensaje
587//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
588//      Devuelve:
589//              TRUE: Si el proceso es correcto
590//              FALSE: En caso de ocurrir algún error
591// ________________________________________________________________________________________________________
592BOOLEAN procesoInclusionCliente(SOCKET *socket_c, TRAMA *ptrTrama) {
593        char msglog[LONSTD], sqlstr[LONSQL];
594        Database db;
595        Table tbl;
596
597        char *iph, *cfg;
598        char nombreordenador[LONFIL];
599        int lon, resul, idordenador, idmenu, cache, idproautoexec, idaula, idcentro;
600        char modulo[] = "procesoInclusionCliente()";
601
602        // Toma parámetros
603        iph = copiaParametro("iph",ptrTrama); // Toma ip
604        cfg = copiaParametro("cfg",ptrTrama); // Toma configuracion
605
606        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexión con la BD
607                errorLog(modulo, 20, FALSE);
608                db.GetErrorErrStr(msglog);
609                errorInfo(modulo, msglog);
610                return (FALSE);
611        }
612
613        // Recupera los datos del cliente
614        sprintf(sqlstr,
615                        "SELECT ordenadores.*,aulas.idaula,centros.idcentro FROM ordenadores "
616                                " INNER JOIN aulas ON aulas.idaula=ordenadores.idaula"
617                                " INNER JOIN centros ON centros.idcentro=aulas.idcentro"
618                                " WHERE ordenadores.ip = '%s'", iph);
619
620        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
621                errorLog(modulo, 21, FALSE);
622                db.GetErrorErrStr(msglog);
623                errorInfo(modulo, msglog);
624                return (FALSE);
625        }
626
627        if (tbl.ISEOF()) { // Si no existe el cliente
628                errorLog(modulo, 22, FALSE);
629                return (FALSE);
630        }
631
632        if (ndebug == DEBUG_ALTO) {
633                sprintf(msglog, "%s IP:%s", tbMensajes[2], iph);
634                infoDebug(msglog);
635        }
636        if (!tbl.Get("idordenador", idordenador)) {
637                tbl.GetErrorErrStr(msglog);
638                errorInfo(modulo, msglog);
639                return (FALSE);
640        }
641        if (!tbl.Get("nombreordenador", nombreordenador)) {
642                tbl.GetErrorErrStr(msglog);
643                errorInfo(modulo, msglog);
644                return (FALSE);
645        }
646        if (!tbl.Get("idmenu", idmenu)) {
647                tbl.GetErrorErrStr(msglog);
648                errorInfo(modulo, msglog);
649                return (FALSE);
650        }
651        if (!tbl.Get("cache", cache)) {
652                tbl.GetErrorErrStr(msglog);
653                errorInfo(modulo, msglog);
654                return (FALSE);
655        }
656        if (!tbl.Get("idproautoexec", idproautoexec)) {
657                tbl.GetErrorErrStr(msglog);
658                errorInfo(modulo, msglog);
659                return (FALSE);
660        }
661        if (!tbl.Get("idaula", idaula)) {
662                tbl.GetErrorErrStr(msglog);
663                errorInfo(modulo, msglog);
664                return (FALSE);
665        }
666        if (!tbl.Get("idcentro", idcentro)) {
667                tbl.GetErrorErrStr(msglog);
668                errorInfo(modulo, msglog);
669                return (FALSE);
670        }
671
672        resul = actualizaConfiguracion(db, tbl, cfg, idordenador); // Actualiza la configuración del ordenador
673        liberaMemoria(cfg);
674        db.Close();
675
676        if (!resul) {
677                liberaMemoria(iph);
678                errorLog(modulo, 29, FALSE);
679                return (FALSE);
680        }
681
682        if (!registraCliente(iph)) { // Incluyendo al cliente en la tabla de sokets
683                liberaMemoria(iph);
684                errorLog(modulo, 25, FALSE);
685                return (FALSE);
686        }
687
688        /*------------------------------------------------------------------------------------------------------------------------------
689         Prepara la trama de respuesta
690         -------------------------------------------------------------------------------------------------------------------------------*/
691        initParametros(ptrTrama,0);
692        ptrTrama->tipo=MSG_RESPUESTA;
693        lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_InclusionCliente\r");
694        lon += sprintf(ptrTrama->parametros + lon, "ido=%d\r", idordenador);
695        lon += sprintf(ptrTrama->parametros + lon, "npc=%s\r", nombreordenador);
696        lon += sprintf(ptrTrama->parametros + lon, "che=%d\r", cache);
697        lon += sprintf(ptrTrama->parametros + lon, "exe=%d\r", idproautoexec);
698        lon += sprintf(ptrTrama->parametros + lon, "ida=%d\r", idaula);
699        lon += sprintf(ptrTrama->parametros + lon, "idc=%d\r", idcentro);
700        lon += sprintf(ptrTrama->parametros + lon, "res=%d\r", 1); // Confirmación proceso correcto
701
702        if (!mandaTrama(socket_c, ptrTrama)) {
703                errorLog(modulo, 26, FALSE);
704                return (FALSE);
705        }
706        liberaMemoria(iph);
707        return (TRUE);
708}
709// ________________________________________________________________________________________________________
710// Función: actualizaConfiguracion
711//
712//      Descripción:
713//              Esta función actualiza la base de datos con la configuracion de particiones de un cliente
714//      Parámetros:
715//              - db: Objeto base de datos (ya operativo)
716//              - tbl: Objeto tabla
717//              - cfg: cadena con una Configuración
718//              - ido: Identificador del ordenador cliente
719//      Devuelve:
720//              TRUE: Si el proceso es correcto
721//              FALSE: En caso de ocurrir algún error
722//      Especificaciones:
723//              Los parametros de la configuración son:
724//                      par= Número de partición
725//                      cpt= Codigo o tipo de partición
726//                      sfi= Sistema de ficheros que está implementado en la partición
727//                      soi= Nombre del sistema de ficheros instalado en la partición
728//                      tam= Tamaño de la partición
729// ________________________________________________________________________________________________________
730BOOLEAN actualizaConfiguracion(Database db, Table tbl, char* cfg, int ido)
731{
732        char msglog[LONSTD], sqlstr[LONSQL];
733        int lon, p, c,i, dato, swu, idsoi, idsfi,k;
734        char *ptrPar[MAXPAR], *ptrCfg[6], *ptrDual[2], tbPar[LONSTD];
735        char *disk, *par, *cpt, *sfi, *soi, *tam; // Parametros que definen una partición
736        char modulo[] = "actualizaConfiguracion()";
737
738        lon = 0;
739        p = splitCadena(ptrPar, cfg, '\n');
740        for (i = 0; i < p; i++) {
741                c = splitCadena(ptrCfg, ptrPar[i], '\t');
742                disk = par = cpt = sfi = soi = tam = NULL;
743                splitCadena(ptrDual, ptrCfg[0], '=');
744                disk = ptrDual[1]; // Número de disco
745
746                splitCadena(ptrDual, ptrCfg[1], '=');
747                par = ptrDual[1]; // Número de partición
748
749                k=splitCadena(ptrDual, ptrCfg[2], '=');
750                if(k==2){
751                        cpt = ptrDual[1]; // Código de partición
752                }else{
753                        cpt = "0";
754                }
755
756                k=splitCadena(ptrDual, ptrCfg[3], '=');
757                if(k==2){
758                        sfi = ptrDual[1]; // Sistema de ficheros
759                        /* Comprueba existencia del s0xistema de ficheros instalado */
760                        idsfi = checkDato(db, tbl, sfi, "sistemasficheros", "descripcion","idsistemafichero");
761                }
762                else
763                        idsfi=0;
764
765                k=splitCadena(ptrDual, ptrCfg[4], '=');
766                if(k==2){ // Sistema operativo detecdtado
767                        soi = ptrDual[1]; // Nombre del S.O. instalado
768                        /* Comprueba existencia del sistema operativo instalado */
769                        idsoi = checkDato(db, tbl, soi, "nombresos", "nombreso", "idnombreso");
770                }
771                else
772                        idsoi=0;
773
774                splitCadena(ptrDual, ptrCfg[5], '=');
775                tam = ptrDual[1]; // Tamaño de la partición
776
777                lon += sprintf(tbPar + lon, "(%s, %s),", disk, par);
778
779                sprintf(sqlstr, "SELECT numdisk,numpar,codpar,tamano,idsistemafichero,idnombreso"
780                                "  FROM ordenadores_particiones WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
781                                ido, disk, par);
782
783
784                if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
785                        errorLog(modulo, 21, FALSE);
786                        db.GetErrorErrStr(msglog);
787                        errorInfo(modulo, msglog);
788                        return (FALSE);
789                }
790                if (tbl.ISEOF()) { // Si no existe el registro
791                        sprintf(sqlstr, "INSERT INTO ordenadores_particiones(idordenador,numdisk,numpar,codpar,tamano,idsistemafichero,idnombreso,idimagen)"
792                                        " VALUES(%d,%s,%s,0x%s,%s,%d,%d,0)",
793                                        ido, disk, par, cpt, tam, idsfi, idsoi);
794
795
796                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
797                                db.GetErrorErrStr(msglog);
798                                errorInfo(modulo, msglog);
799                                return (FALSE);
800                        }
801                } else { // Existe el registro
802                        swu = TRUE; // Se supone que algún dato ha cambiado
803                        if (!tbl.Get("codpar", dato)) { // Toma dato
804                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
805                                errorInfo(modulo, msglog);
806                                return (FALSE);
807                        }
808                        if (strtol(cpt, NULL, 16) == dato) {// Parámetro tipo de partición (hexadecimal) igual al almacenado (decimal)
809                                if (!tbl.Get("tamano", dato)) { // Toma dato
810                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
811                                        errorInfo(modulo, msglog);
812                                        return (FALSE);
813                                }
814                                if (atoi(tam) == dato) {// Parámetro tamaño igual al almacenado
815                                        if (!tbl.Get("idsistemafichero", dato)) { // Toma dato
816                                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
817                                                errorInfo(modulo, msglog);
818                                                return (FALSE);
819                                        }
820                                        if (idsfi == dato) {// Parámetro sistema de fichero igual al almacenado
821                                                if (!tbl.Get("idnombreso", dato)) { // Toma dato
822                                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
823                                                        errorInfo(modulo, msglog);
824                                                        return (FALSE);
825                                                }
826                                                if (idsoi == dato) {// Parámetro sistema de fichero distinto al almacenado
827                                                        swu = FALSE; // Todos los parámetros de la partición son iguales, no se actualiza
828                                                }
829                                        }
830                                }
831                        }
832                        if (swu) { // Hay que actualizar los parámetros de la partición
833                                sprintf(sqlstr, "UPDATE ordenadores_particiones SET "
834                                        " codpar=0x%s,"
835                                        " tamano=%s,"
836                                        " idsistemafichero=%d,"
837                                        " idnombreso=%d,"
838                                        " idimagen=0,"
839                                        " idperfilsoft=0,"
840                                        " fechadespliegue=NULL"
841                                        " WHERE idordenador=%d AND numdisk=%s AND numpar=%s",
842                                        cpt, tam, idsfi, idsoi, ido, disk, par);
843                                if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
844                                        errorLog(modulo, 21, FALSE);
845                                        db.GetErrorErrStr(msglog);
846                                        errorInfo(modulo, msglog);
847                                        return (FALSE);
848                                }
849                        }
850                }
851        }
852        lon += sprintf(tbPar + lon, "(0,0)");
853        // Eliminar particiones almacenadas que ya no existen
854        sprintf(sqlstr, "DELETE FROM ordenadores_particiones WHERE idordenador=%d AND (numdisk, numpar) NOT IN (%s)",
855                        ido, tbPar);
856        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
857                errorLog(modulo, 21, FALSE);
858                db.GetErrorErrStr(msglog);
859                errorInfo(modulo, msglog);
860                return (FALSE);
861        }
862        return (TRUE);
863}
864// ________________________________________________________________________________________________________
865// Función: checkDato
866//
867//      Descripción:
868//               Esta función comprueba si existe un dato en una tabla y si no es así lo incluye. devuelve en
869//              cualquier caso el identificador del registro existenet o del insertado
870//      Parámetros:
871//              - db: Objeto base de datos (ya operativo)
872//              - tbl: Objeto tabla
873//              - dato: Dato
874//              - tabla: Nombre de la tabla
875//              - nomdato: Nombre del dato en la tabla
876//              - nomidentificador: Nombre del identificador en la tabla
877//      Devuelve:
878//              El identificador del registro existente o el del insertado
879//
880//      Especificaciones:
881//              En caso de producirse algún error se devuelve el valor 0
882// ________________________________________________________________________________________________________
883
884int checkDato(Database db, Table tbl, char *dato, const char*tabla,
885                const char* nomdato, const char *nomidentificador) {
886        char msglog[LONSTD], sqlstr[LONSQL];
887        char modulo[] = "checkDato()";
888        int identificador;
889
890        if (strlen(dato) == 0)
891                return (0); // EL dato no tiene valor
892        sprintf(sqlstr, "SELECT %s FROM %s WHERE %s ='%s'", nomidentificador,
893                        tabla, nomdato, dato);
894
895        // Ejecuta consulta
896        if (!db.Execute(sqlstr, tbl)) { // Error al leer
897                errorLog(modulo, 21, FALSE);
898                db.GetErrorErrStr(msglog);
899                errorInfo(modulo, msglog);
900                return (0);
901        }
902        if (tbl.ISEOF()) { //  Software NO existente
903                sprintf(sqlstr, "INSERT INTO %s (%s) VALUES('%s')", tabla, nomdato, dato);
904                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
905                        db.GetErrorErrStr(msglog); // Error al acceder al registro
906                        errorInfo(modulo, msglog);
907                        return (0);
908                }
909                // Recupera el identificador del software
910                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
911                if (!db.Execute(sqlstr, tbl)) { // Error al leer
912                        db.GetErrorErrStr(msglog); // Error al acceder al registro
913                        errorInfo(modulo, msglog);
914                        return (0);
915                }
916                if (!tbl.ISEOF()) { // Si existe registro
917                        if (!tbl.Get("identificador", identificador)) {
918                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
919                                errorInfo(modulo, msglog);
920                                return (0);
921                        }
922                }
923        } else {
924                if (!tbl.Get(nomidentificador, identificador)) { // Toma dato
925                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
926                        errorInfo(modulo, msglog);
927                        return (0);
928                }
929        }
930        return (identificador);
931}
932// ________________________________________________________________________________________________________
933// Función: registraCliente
934//
935//      Descripción:
936//               Incluye al cliente en la tabla de sokets
937//      Parámetros:
938//              - iph: Dirección ip del cliente
939//      Devuelve:
940//              TRUE: Si el proceso es correcto
941//              FALSE: En caso de ocurrir algún error
942// ________________________________________________________________________________________________________
943BOOLEAN registraCliente(char *iph) {
944        int idx;
945
946        if (!clienteExistente(iph, &idx)) { // Si no existe la IP ...
947                if (!hayHueco(&idx)) { // Busca hueco para el nuevo cliente
948                        return (FALSE); // No hay huecos
949                }
950        }
951        strcpy(tbsockets[idx].ip, iph); // Copia IP
952        strcpy(tbsockets[idx].estado, CLIENTE_INICIANDO); // Actualiza el estado del cliente
953        return (TRUE);
954}
955// ________________________________________________________________________________________________________
956// Función: AutoexecCliente
957//
958//      Descripción:
959//              Envía archivo de autoexec al cliente
960//      Parámetros:
961//              - socket_c: Socket del cliente que envió el mensaje
962//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
963//      Devuelve:
964//              TRUE: Si el proceso es correcto
965//              FALSE: En caso de ocurrir algún error
966// ________________________________________________________________________________________________________
967BOOLEAN AutoexecCliente(SOCKET *socket_c, TRAMA *ptrTrama) {
968        int lon;
969        char *iph, *exe, msglog[LONSTD];
970        Database db;
971        FILE *fileexe;
972        char fileautoexec[LONPRM];
973        char parametros[LONGITUD_PARAMETROS];
974        char modulo[] = "AutoexecCliente()";
975
976        iph = copiaParametro("iph",ptrTrama); // Toma dirección IP del cliente
977        exe = copiaParametro("exe",ptrTrama); // Toma identificador del procedimiento inicial
978
979        sprintf(fileautoexec, "/tmp/Sautoexec-%s", iph);
980        liberaMemoria(iph);
981        fileexe = fopen(fileautoexec, "wb"); // Abre fichero de script
982        if (fileexe == NULL) {
983                errorLog(modulo, 52, FALSE);
984                return (FALSE);
985        }
986
987        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexión con la BD
988                errorLog(modulo, 20, FALSE);
989                db.GetErrorErrStr(msglog);
990                errorInfo(modulo, msglog);
991                return (FALSE);
992        }
993        initParametros(ptrTrama,0);
994        if (recorreProcedimientos(db, parametros, fileexe, exe)) {
995                lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_AutoexecCliente\r");
996                lon += sprintf(ptrTrama->parametros + lon, "nfl=%s\r", fileautoexec);
997                lon += sprintf(ptrTrama->parametros + lon, "res=1\r");
998        } else {
999                lon = sprintf(ptrTrama->parametros, "nfn=RESPUESTA_AutoexecCliente\r");
1000                lon += sprintf(ptrTrama->parametros + lon, "res=0\r");
1001        }
1002
1003        db.Close();
1004        fclose(fileexe);
1005
1006        if (!mandaTrama(socket_c, ptrTrama)) {
1007                liberaMemoria(exe);
1008                errorLog(modulo, 26, FALSE);
1009                return (FALSE);
1010        }
1011        liberaMemoria(exe);
1012        return (TRUE);
1013}
1014// ________________________________________________________________________________________________________
1015// Función: recorreProcedimientos
1016//
1017//      Descripción:
1018//              Crea un archivo con el código de un procedimiento separando cada comando  por un salto de linea
1019//      Parámetros:
1020//              Database db,char* parametros,FILE* fileexe,char* idp
1021//      Devuelve:
1022//              TRUE: Si el proceso es correcto
1023//              FALSE: En caso de ocurrir algún error
1024// ________________________________________________________________________________________________________
1025BOOLEAN recorreProcedimientos(Database db, char* parametros, FILE* fileexe,
1026                char* idp) {
1027        int procedimientoid, lsize;
1028        char idprocedimiento[LONPRM], msglog[LONSTD], sqlstr[LONSQL];
1029        Table tbl;
1030        char modulo[] = "recorreProcedimientos()";
1031
1032        /* Busca procedimiento */
1033        sprintf(sqlstr,
1034                        "SELECT procedimientoid,parametros FROM procedimientos_acciones"
1035                                " WHERE idprocedimiento=%s ORDER BY orden", idp);
1036        // Ejecuta consulta
1037        if (!db.Execute(sqlstr, tbl)) { // Error al leer
1038                errorLog(modulo, 21, FALSE);
1039                db.GetErrorErrStr(msglog);
1040                errorInfo(modulo, msglog);
1041                return (FALSE);
1042        }
1043        while (!tbl.ISEOF()) { // Recorre procedimientos
1044                if (!tbl.Get("procedimientoid", procedimientoid)) { // Toma dato
1045                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1046                        errorInfo(modulo, msglog);
1047                        return (FALSE);
1048                }
1049                if (procedimientoid > 0) { // Procedimiento recursivo
1050                        sprintf(idprocedimiento, "%d", procedimientoid);
1051                        if (!recorreProcedimientos(db, parametros, fileexe, idprocedimiento)) {
1052                                return (FALSE);
1053                        }
1054                } else {
1055                        if (!tbl.Get("parametros", parametros)) { // Toma dato
1056                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1057                                errorInfo(modulo, msglog);
1058                                return (FALSE);
1059                        }
1060                        strcat(parametros, "@");
1061                        lsize = strlen(parametros);
1062                        fwrite(parametros, 1, lsize, fileexe); // Escribe el código a ejecutar
1063                }
1064                tbl.MoveNext();
1065        }
1066        return (TRUE);
1067}
1068// ________________________________________________________________________________________________________
1069// Función: ComandosPendientes
1070//
1071//      Descripción:
1072//              Esta función busca en la base de datos,comandos pendientes de ejecutar por un  ordenador  concreto
1073//      Parámetros:
1074//              - socket_c: Socket del cliente que envió el mensaje
1075//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1076//      Devuelve:
1077//              TRUE: Si el proceso es correcto
1078//              FALSE: En caso de ocurrir algún error
1079// ________________________________________________________________________________________________________
1080BOOLEAN ComandosPendientes(SOCKET *socket_c, TRAMA *ptrTrama)
1081{
1082        char *ido,*iph,pids[LONPRM];
1083        int ids, idx;
1084        char modulo[] = "ComandosPendientes()";
1085
1086        iph = copiaParametro("iph",ptrTrama); // Toma dirección IP
1087        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1088
1089        if (!clienteExistente(iph, &idx)) { // Busca índice del cliente
1090                liberaMemoria(iph);
1091                liberaMemoria(ido);
1092                errorLog(modulo, 47, FALSE);
1093                return (FALSE);
1094        }
1095        if (buscaComandos(ido, ptrTrama, &ids)) { // Existen comandos pendientes
1096                ptrTrama->tipo = MSG_COMANDO;
1097                sprintf(pids, "\rids=%d\r", ids);
1098                strcat(ptrTrama->parametros, pids);
1099                strcpy(tbsockets[idx].estado, CLIENTE_OCUPADO);
1100        } else {
1101                initParametros(ptrTrama,0);
1102                strcpy(ptrTrama->parametros, "nfn=NoComandosPtes\r");
1103        }
1104        if (!mandaTrama(socket_c, ptrTrama)) {
1105                liberaMemoria(iph);
1106                liberaMemoria(ido);     
1107                errorLog(modulo, 26, FALSE);
1108                return (FALSE);
1109        }
1110        liberaMemoria(iph);
1111        liberaMemoria(ido);     
1112        return (TRUE);
1113}
1114// ________________________________________________________________________________________________________
1115// Función: buscaComandos
1116//
1117//      Descripción:
1118//              Busca en la base de datos,comandos pendientes de ejecutar por el cliente
1119//      Parámetros:
1120//              - ido: Identificador del ordenador
1121//              - cmd: Parámetros del comando (Salida)
1122//              - ids: Identificador de la sesion(Salida)
1123//      Devuelve:
1124//              TRUE: Si el proceso es correcto
1125//              FALSE: En caso de ocurrir algún error
1126// ________________________________________________________________________________________________________
1127BOOLEAN buscaComandos(char *ido, TRAMA *ptrTrama, int *ids)
1128{
1129        char msglog[LONSTD], sqlstr[LONSQL];
1130        Database db;
1131        Table tbl;
1132        int lonprm;
1133
1134        char modulo[] = "buscaComandos()";
1135
1136        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexión con la BD
1137                errorLog(modulo, 20, FALSE);
1138                db.GetErrorErrStr(msglog);
1139                errorInfo(modulo, msglog);
1140                return (FALSE);
1141        }
1142        sprintf(sqlstr,"SELECT sesion,parametros,length( parametros) as lonprm"\
1143                        " FROM acciones WHERE idordenador=%s AND estado='%d' ORDER BY idaccion", ido, ACCION_INICIADA);
1144        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
1145                errorLog(modulo, 21, FALSE);
1146                db.GetErrorErrStr(msglog);
1147                errorInfo(modulo, msglog);
1148                return (FALSE);
1149        }
1150        if (tbl.ISEOF()) {
1151                db.Close();
1152                return (FALSE); // No hay comandos pendientes
1153        } else { // Busca entre todas las acciones de diversos ambitos
1154                if (!tbl.Get("sesion", *ids)) { // Toma identificador de la sesion
1155                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1156                        errorInfo(modulo, msglog);
1157                        return (FALSE);
1158                }
1159                if (!tbl.Get("lonprm", lonprm)) { // Toma parámetros del comando
1160                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1161                        errorInfo(modulo, msglog);
1162                        return (FALSE);
1163                }
1164                if(!initParametros(ptrTrama,lonprm+LONGITUD_PARAMETROS)){
1165                        db.Close();
1166                        errorLog(modulo, 3, FALSE);
1167                        return (FALSE);
1168                }
1169                if (!tbl.Get("parametros", ptrTrama->parametros)) { // Toma parámetros del comando
1170                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1171                        errorInfo(modulo, msglog);
1172                        return (FALSE);
1173                }
1174        }
1175        db.Close();
1176        return (TRUE); // Hay comandos pendientes, se toma el primero de la cola
1177}
1178// ________________________________________________________________________________________________________
1179// Función: DisponibilidadComandos
1180//
1181//      Descripción:
1182//              Esta función habilita a un cliente para recibir comandos desde la consola
1183//      Parámetros:
1184//              - socket_c: Socket del cliente que envió el mensaje
1185//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1186//      Devuelve:
1187//              TRUE: Si el proceso es correcto
1188//              FALSE: En caso de ocurrir algún error
1189// ________________________________________________________________________________________________________
1190//
1191BOOLEAN DisponibilidadComandos(SOCKET *socket_c, TRAMA *ptrTrama)
1192{
1193        char *iph, *tpc;
1194        int idx,port_old=0,port_new;
1195        char modulo[] = "DisponibilidadComandos()";
1196       
1197
1198
1199        iph = copiaParametro("iph",ptrTrama); // Toma ip
1200        if (!clienteExistente(iph, &idx)) { // Busca índice del cliente
1201                liberaMemoria(iph);
1202                errorLog(modulo, 47, FALSE);
1203                return (FALSE);
1204        }
1205        tpc = copiaParametro("tpc",ptrTrama); // Tipo de cliente (Plataforma y S.O.)
1206        strcpy(tbsockets[idx].estado, tpc);
1207
1208        port_new=tomaPuerto(*socket_c);
1209
1210        if(tbsockets[idx].sock!=INVALID_SOCKET){
1211                port_old=tomaPuerto(tbsockets[idx].sock);
1212                if(port_old!=port_new){
1213                        close(tbsockets[idx].sock); // Cierra el socket si ya existia uno
1214                }
1215        }
1216
1217        tbsockets[idx].sock = *socket_c;
1218        swcSocket = TRUE; // El socket permanece abierto para recibir comandos desde el servidor
1219        liberaMemoria(iph);
1220        liberaMemoria(tpc);             
1221        return (TRUE);
1222}
1223// ________________________________________________________________________________________________________
1224// Función: respuestaEstandar
1225//
1226//      Descripción:
1227//              Esta función actualiza la base de datos con el resultado de la ejecución de un comando con seguimiento
1228//      Parámetros:
1229//              - res: resultado de la ejecución del comando
1230//              - der: Descripción del error si hubiese habido
1231//              - iph: Dirección IP
1232//              - ids: identificador de la sesión
1233//              - ido: Identificador del ordenador que notifica
1234//              - db: Objeto base de datos (operativo)
1235//              - tbl: Objeto tabla
1236//      Devuelve:
1237//              TRUE: Si el proceso es correcto
1238//              FALSE: En caso de ocurrir algún error
1239// ________________________________________________________________________________________________________
1240BOOLEAN respuestaEstandar(TRAMA *ptrTrama, char *iph, char *ido, Database db,
1241                Table tbl) {
1242        char msglog[LONSTD], sqlstr[LONSQL];
1243        char *res, *ids, *der;
1244        char fechafin[LONPRM];
1245        struct tm* st;
1246        int idaccion;
1247        char modulo[] = "respuestaEstandar()";
1248
1249        ids = copiaParametro("ids",ptrTrama); // Toma identificador de la sesión
1250
1251        if (ids == NULL) // No existe seguimiento de la acción
1252                return (TRUE);
1253               
1254        if (atoi(ids) == 0){ // No existe seguimiento de la acción
1255                liberaMemoria(ids);
1256                return (TRUE);
1257        }
1258
1259        sprintf(sqlstr,
1260                        "SELECT * FROM acciones WHERE idordenador=%s"
1261                        " AND sesion=%s ORDER BY idaccion", ido,ids);
1262
1263        liberaMemoria(ids);
1264
1265        if (!db.Execute(sqlstr, tbl)) { // Error al consultar
1266                errorLog(modulo, 21, FALSE);
1267                db.GetErrorErrStr(msglog);
1268                errorInfo(modulo, msglog);
1269                return (FALSE);
1270        }
1271        if (tbl.ISEOF()) { // No existe registro de acciones
1272                errorLog(modulo, 31, FALSE);
1273                return (TRUE);
1274        }
1275        if (!tbl.Get("idaccion", idaccion)) { // Toma identificador de la accion
1276                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
1277                errorInfo(modulo, msglog);
1278                return (FALSE);
1279        }
1280        st = tomaHora();
1281        sprintf(fechafin, "%d/%d/%d %d:%d:%d", st->tm_year + 1900, st->tm_mon + 1,
1282                        st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
1283
1284        res = copiaParametro("res",ptrTrama); // Toma resultado
1285        der = copiaParametro("der",ptrTrama); // Toma descripción del error (si hubiera habido)
1286       
1287        sprintf(sqlstr,
1288                        "UPDATE acciones"\
1289                        "   SET resultado='%s',estado='%d',fechahorafin='%s',descrinotificacion='%s'"\
1290                        " WHERE idordenador=%s AND idaccion=%d",
1291                        res, ACCION_FINALIZADA, fechafin, der, ido, idaccion);
1292                       
1293        if (!db.Execute(sqlstr, tbl)) { // Error al actualizar
1294                liberaMemoria(res);
1295                liberaMemoria(der);
1296                db.GetErrorErrStr(msglog);
1297                errorInfo(modulo, msglog);
1298                return (FALSE);
1299        }
1300       
1301        liberaMemoria(der);
1302       
1303        if (atoi(res) == ACCION_FALLIDA) {
1304                liberaMemoria(res);
1305                return (FALSE); // Error en la ejecución del comando
1306        }
1307
1308        liberaMemoria(res);
1309        return (TRUE);
1310}
1311// ________________________________________________________________________________________________________
1312// Función: enviaComando
1313//
1314//      Descripción:
1315//              Envía un comando a los clientes
1316//      Parámetros:
1317//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1318//              - estado: Estado en el se deja al cliente mientras se ejecuta el comando
1319//      Devuelve:
1320//              TRUE: Si el proceso es correcto
1321//              FALSE: En caso de ocurrir algún error
1322// ________________________________________________________________________________________________________
1323BOOLEAN enviaComando(TRAMA* ptrTrama, const char *estado)
1324 {
1325        char *iph, *Ipes, *ptrIpes[MAXIMOS_CLIENTES];
1326        int i, idx, lon;
1327        char modulo[] = "enviaComando()";
1328
1329        iph = copiaParametro("iph",ptrTrama); // Toma dirección/es IP
1330        lon = strlen(iph); // Calcula longitud de la cadena de direccion/es IPE/S
1331        Ipes = (char*) reservaMemoria(lon + 1);
1332        if (Ipes == NULL) {
1333                errorLog(modulo, 3, FALSE);
1334                return (FALSE);
1335        }
1336       
1337        strcpy(Ipes, iph); // Copia cadena de IPES
1338        liberaMemoria(iph);
1339
1340        lon = splitCadena(ptrIpes, Ipes, ';');
1341        FINCADaINTRO(ptrTrama);
1342        for (i = 0; i < lon; i++) {
1343                if (clienteDisponible(ptrIpes[i], &idx)) { // Si el cliente puede recibir comandos
1344                        strcpy(tbsockets[idx].estado, estado); // Actualiza el estado del cliente
1345                        if (!mandaTrama(&tbsockets[idx].sock, ptrTrama)) {
1346                                errorLog(modulo, 26, FALSE);
1347                                return (FALSE);
1348                        }
1349                        //close(tbsockets[idx].sock); // Cierra el socket del cliente hasta nueva disponibilidad
1350                }
1351        }
1352        liberaMemoria(Ipes);
1353        return (TRUE);
1354}
1355//______________________________________________________________________________________________________
1356// Función: respuestaConsola
1357//
1358//      Descripción:
1359//              Envia una respuesta a la consola sobre el resultado de la ejecución de un comando
1360//      Parámetros:
1361//              - socket_c: (Salida) Socket utilizado para el envío
1362//              - res: Resultado del envío del comando
1363//      Devuelve:
1364//              TRUE: Si el proceso es correcto
1365//              FALSE: En caso de ocurrir algún error
1366// ________________________________________________________________________________________________________
1367BOOLEAN respuestaConsola(SOCKET *socket_c, TRAMA *ptrTrama, int res) {
1368        char modulo[] = "respuestaConsola()";
1369        initParametros(ptrTrama,0);
1370        sprintf(ptrTrama->parametros, "res=%d\r", res);
1371        if (!mandaTrama(socket_c, ptrTrama)) {
1372                errorLog(modulo, 26, FALSE);
1373                return (FALSE);
1374        }
1375        return (TRUE);
1376}
1377// ________________________________________________________________________________________________________
1378// Función: Arrancar
1379//
1380//      Descripción:
1381//              Procesa el comando Arrancar
1382//      Parámetros:
1383//              - socket_c: Socket de la consola al envió el mensaje
1384//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1385//      Devuelve:
1386//              TRUE: Si el proceso es correcto
1387//              FALSE: En caso de ocurrir algún error
1388// ________________________________________________________________________________________________________
1389BOOLEAN Arrancar(SOCKET *socket_c, TRAMA* ptrTrama) {
1390        char *iph,*mac,*mar, msglog[LONSTD];
1391        BOOLEAN res;
1392        char modulo[] = "Arrancar()";
1393
1394        iph = copiaParametro("iph",ptrTrama); // Toma dirección/es IP
1395        mac = copiaParametro("mac",ptrTrama); // Toma dirección/es MAC
1396        mar = copiaParametro("mar",ptrTrama); // Método de arranque (Broadcast o Unicast)
1397
1398        res=Levanta(iph,mac,mar);
1399
1400        liberaMemoria(iph);
1401        liberaMemoria(mac);
1402        liberaMemoria(mar);
1403
1404        if(!res){
1405                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1406                errorInfo(modulo, msglog);
1407                respuestaConsola(socket_c, ptrTrama, FALSE);
1408                return (FALSE);
1409        }
1410
1411        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1412                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1413                errorInfo(modulo, msglog);
1414                respuestaConsola(socket_c, ptrTrama, FALSE);
1415                return (FALSE);
1416        }
1417        respuestaConsola(socket_c, ptrTrama, TRUE);
1418        return (TRUE);
1419}
1420// ________________________________________________________________________________________________________
1421// Función: Levanta
1422//
1423//      Descripción:
1424//              Enciende ordenadores a través de la red cuyas macs se pasan como parámetro
1425//      Parámetros:
1426//              - iph: Cadena de direcciones ip separadas por ";"
1427//              - mac: Cadena de direcciones mac separadas por ";"
1428//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
1429//      Devuelve:
1430//              TRUE: Si el proceso es correcto
1431//              FALSE: En caso de ocurrir algún error
1432// ________________________________________________________________________________________________________
1433BOOLEAN Levanta(char* iph,char *mac, char* mar)
1434{
1435        char *ptrIP[MAXIMOS_CLIENTES],*ptrMacs[MAXIMOS_CLIENTES];
1436        int i, lon, res;
1437        SOCKET s;
1438        BOOLEAN bOpt;
1439        sockaddr_in local;
1440        char modulo[] = "Levanta()";
1441
1442        /* Creación de socket para envío de magig packet */
1443        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1444        if (s == SOCKET_ERROR) { // Error al crear el socket del servicio
1445                errorLog(modulo, 13, TRUE);
1446                return (FALSE);
1447        }
1448        bOpt = TRUE; // Pone el socket en modo Broadcast
1449        res = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &bOpt, sizeof(bOpt));
1450        if (res == SOCKET_ERROR) {
1451                errorLog(modulo, 48, TRUE);
1452                return (FALSE);
1453        }
1454        local.sin_family = AF_INET;
1455        local.sin_port = htons((short) PUERTO_WAKEUP);
1456        local.sin_addr.s_addr = htonl(INADDR_ANY); // cualquier interface
1457        if (bind(s, (sockaddr *) &local, sizeof(local)) == SOCKET_ERROR) {
1458                errorLog(modulo, 14, TRUE);
1459                exit(EXIT_FAILURE);
1460        }
1461        /* fin creación de socket */
1462        lon = splitCadena(ptrIP, iph, ';');
1463        lon = splitCadena(ptrMacs, mac, ';');
1464        for (i = 0; i < lon; i++) {
1465                if (!WakeUp(&s,ptrIP[i],ptrMacs[i],mar)) {
1466                        errorLog(modulo, 49, TRUE);
1467                        close(s);
1468                        return (FALSE);
1469                }
1470        }
1471        close(s);
1472        return (TRUE);
1473}
1474//_____________________________________________________________________________________________________________
1475// Función: WakeUp
1476//
1477//       Descripción:
1478//              Enciende el ordenador cuya MAC se pasa como parámetro
1479//      Parámetros:
1480//              - s : Socket para enviar trama magic packet
1481//              - iph : Cadena con la dirección ip
1482//              - mac : Cadena con la dirección mac en formato XXXXXXXXXXXX
1483//              - mar: Método de arranque (1=Broadcast, 2=Unicast)
1484//      Devuelve:
1485//              TRUE: Si el proceso es correcto
1486//              FALSE: En caso de ocurrir algún error
1487//_____________________________________________________________________________________________________________
1488//
1489BOOLEAN WakeUp(SOCKET *s, char* iph,char *mac,char* mar)
1490{
1491        int i, res;
1492        char HDaddress_bin[6];
1493        struct {
1494                BYTE secuencia_FF[6];
1495                char macbin[16][6];
1496        } Trama_WakeUp;
1497        sockaddr_in WakeUpCliente;
1498        char modulo[] = "WakeUp()";
1499
1500        for (i = 0; i < 6; i++) // Primera secuencia de la trama Wake Up (0xFFFFFFFFFFFF)
1501                Trama_WakeUp.secuencia_FF[i] = 0xFF;
1502
1503        PasaHexBin(mac, HDaddress_bin); // Pasa a binario la MAC
1504
1505        for (i = 0; i < 16; i++) // Segunda secuencia de la trama Wake Up , repetir 16 veces su la MAC
1506                memcpy(&Trama_WakeUp.macbin[i][0], &HDaddress_bin, 6);
1507
1508        /* Creación de socket del cliente que recibe la trama magic packet */
1509        WakeUpCliente.sin_family = AF_INET;
1510        WakeUpCliente.sin_port = htons((short) PUERTO_WAKEUP);
1511        if(atoi(mar)==2)
1512                WakeUpCliente.sin_addr.s_addr = inet_addr(iph); //  Para hacerlo con IP
1513        else
1514                WakeUpCliente.sin_addr.s_addr = htonl(INADDR_BROADCAST); //  Para hacerlo con broadcast
1515
1516        res = sendto(*s, (char *) &Trama_WakeUp, sizeof(Trama_WakeUp), 0,
1517                        (sockaddr *) &WakeUpCliente, sizeof(WakeUpCliente));
1518        if (res == SOCKET_ERROR) {
1519                errorLog(modulo, 26, FALSE);
1520                return (FALSE);
1521        }
1522        return (TRUE);
1523}
1524//_____________________________________________________________________________________________________________
1525// Función: PasaHexBin
1526//
1527//      Descripción:
1528//              Convierte a binario una dirección mac desde una cadena con formato XXXXXXXXXXXX
1529//
1530//      Parámetros de entrada:
1531//              - cadena : Cadena con el contenido de la mac
1532//              - numero : la dirección mac convertida a binario (6 bytes)
1533//_____________________________________________________________________________________________________________
1534void PasaHexBin(char *cadena, char *numero) {
1535        int i, j, p;
1536        char matrizHex[] = "0123456789ABCDEF";
1537        char Ucadena[12], aux;
1538
1539        for (i = 0; i < 12; i++)
1540                Ucadena[i] = toupper(cadena[i]);
1541        p = 0;
1542        for (i = 0; i < 12; i++) {
1543                for (j = 0; j < 16; j++) {
1544                        if (Ucadena[i] == matrizHex[j]) {
1545                                if (i % 2) {
1546                                        aux = numero[p];
1547                                        aux = (aux << 4);
1548                                        numero[p] = j;
1549                                        numero[p] = numero[p] | aux;
1550                                        p++;
1551                                } else
1552                                        numero[p] = j;
1553                                break;
1554                        }
1555                }
1556        }
1557}
1558// ________________________________________________________________________________________________________
1559// Función: RESPUESTA_Arrancar
1560//
1561//      Descripción:
1562//              Respuesta del cliente al comando Arrancar
1563//      Parámetros:
1564//              - socket_c: Socket del cliente que envió el mensaje
1565//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1566//      Devuelve:
1567//              TRUE: Si el proceso es correcto
1568//              FALSE: En caso de ocurrir algún error
1569// ________________________________________________________________________________________________________
1570BOOLEAN RESPUESTA_Arrancar(SOCKET *socket_c, TRAMA* ptrTrama) {
1571        char msglog[LONSTD];
1572        Database db;
1573        Table tbl;
1574        int i;
1575        char *iph, *ido;
1576        char *tpc;
1577        char modulo[] = "RESPUESTA_Arrancar()";
1578
1579        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1580                errorLog(modulo, 20, FALSE);
1581                db.GetErrorErrStr(msglog);
1582                errorInfo(modulo, msglog);
1583                return (FALSE);
1584        }
1585
1586        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1587        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1588
1589        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1590                liberaMemoria(iph);
1591                liberaMemoria(ido);
1592                errorLog(modulo, 30, FALSE);
1593                return (FALSE); // Error al registrar notificacion
1594        }
1595
1596        tpc = copiaParametro("tpc",ptrTrama); // Tipo de cliente (Plataforma y S.O.)
1597        if (clienteExistente(iph, &i)) // Actualiza estado
1598                strcpy(tbsockets[i].estado, tpc);
1599               
1600        liberaMemoria(iph);
1601        liberaMemoria(ido);
1602        liberaMemoria(tpc);
1603       
1604        db.Close(); // Cierra conexión
1605        return (TRUE);
1606}
1607// ________________________________________________________________________________________________________
1608// Función: Comando
1609//
1610//      Descripción:
1611//              Procesa un comando personalizado
1612//      Parámetros:
1613//              - socket_c: Socket de la consola al envió el mensaje
1614//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1615//      Devuelve:
1616//              TRUE: Si el proceso es correcto
1617//              FALSE: En caso de ocurrir algún error
1618// ________________________________________________________________________________________________________
1619BOOLEAN Comando(SOCKET *socket_c, TRAMA* ptrTrama) {
1620        char msglog[LONSTD];
1621        char modulo[] = "Comando()";
1622
1623        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1624                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1625                errorInfo(modulo, msglog);
1626                respuestaConsola(socket_c, ptrTrama, FALSE);
1627                return (FALSE);
1628        }
1629        respuestaConsola(socket_c, ptrTrama, TRUE);
1630        return (TRUE);
1631}
1632// ________________________________________________________________________________________________________
1633// Función: RESPUESTA_Comando
1634//
1635//      Descripción:
1636//              Respuesta del cliente al un comando personalizado
1637//      Parámetros:
1638//              - socket_c: Socket del cliente que envió el mensaje
1639//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1640//      Devuelve:
1641//              TRUE: Si el proceso es correcto
1642//              FALSE: En caso de ocurrir algún error
1643// ________________________________________________________________________________________________________
1644BOOLEAN RESPUESTA_Comando(SOCKET *socket_c, TRAMA* ptrTrama)
1645 {
1646        char msglog[LONSTD];
1647        Database db;
1648        Table tbl;
1649        char *iph, *ido;
1650        char modulo[] = "RESPUESTA_Comando()";
1651
1652        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1653                errorLog(modulo, 20, FALSE);
1654                db.GetErrorErrStr(msglog);
1655                errorInfo(modulo, msglog);
1656                return (FALSE);
1657        }
1658
1659        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1660        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1661
1662        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1663                liberaMemoria(iph);
1664                liberaMemoria(ido);
1665                errorLog(modulo, 30, FALSE);
1666                return (FALSE); // Error al registrar notificacion
1667        }
1668        liberaMemoria(iph);
1669        liberaMemoria(ido);
1670        db.Close(); // Cierra conexión
1671        return (TRUE);
1672}
1673// ________________________________________________________________________________________________________
1674// Función: Apagar
1675//
1676//      Descripción:
1677//              Procesa el comando Apagar
1678//      Parámetros:
1679//              - socket_c: Socket de la consola al envió el mensaje
1680//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1681//      Devuelve:
1682//              TRUE: Si el proceso es correcto
1683//              FALSE: En caso de ocurrir algún error
1684// ________________________________________________________________________________________________________
1685BOOLEAN Apagar(SOCKET *socket_c, TRAMA* ptrTrama) {
1686        char msglog[LONSTD];
1687        char modulo[] = "Apagar()";
1688
1689        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1690                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1691                errorInfo(modulo, msglog);
1692                respuestaConsola(socket_c, ptrTrama, FALSE);
1693                return (FALSE);
1694        }
1695        respuestaConsola(socket_c, ptrTrama, TRUE);
1696        return (TRUE);
1697}
1698// ________________________________________________________________________________________________________
1699// Función: RESPUESTA_Apagar
1700//
1701//      Descripción:
1702//              Respuesta del cliente al comando Apagar
1703//      Parámetros:
1704//              - socket_c: Socket del cliente que envió el mensaje
1705//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1706//      Devuelve:
1707//              TRUE: Si el proceso es correcto
1708//              FALSE: En caso de ocurrir algún error
1709// ________________________________________________________________________________________________________
1710BOOLEAN RESPUESTA_Apagar(SOCKET *socket_c, TRAMA* ptrTrama) {
1711        char msglog[LONSTD];
1712        Database db;
1713        Table tbl;
1714        int i;
1715        char *iph, *ido;
1716        char modulo[] = "RESPUESTA_Apagar()";
1717
1718        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1719                errorLog(modulo, 20, FALSE);
1720                db.GetErrorErrStr(msglog);
1721                errorInfo(modulo, msglog);
1722                return (FALSE);
1723        }
1724
1725        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1726        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1727
1728        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1729                liberaMemoria(iph);
1730                liberaMemoria(ido);
1731                errorLog(modulo, 30, FALSE);
1732                return (FALSE); // Error al registrar notificacion
1733        }
1734
1735        if (clienteExistente(iph, &i)) // Actualiza estado
1736                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
1737       
1738        liberaMemoria(iph);
1739        liberaMemoria(ido);
1740       
1741        db.Close(); // Cierra conexión
1742        return (TRUE);
1743}
1744// ________________________________________________________________________________________________________
1745// Función: Reiniciar
1746//
1747//      Descripción:
1748//              Procesa el comando Reiniciar
1749//      Parámetros:
1750//              - socket_c: Socket de la consola al envió el mensaje
1751//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1752//      Devuelve:
1753//              TRUE: Si el proceso es correcto
1754//              FALSE: En caso de ocurrir algún error
1755// ________________________________________________________________________________________________________
1756BOOLEAN Reiniciar(SOCKET *socket_c, TRAMA* ptrTrama) {
1757        char msglog[LONSTD];
1758        char modulo[] = "Reiniciar()";
1759
1760        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1761                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1762                errorInfo(modulo, msglog);
1763                respuestaConsola(socket_c, ptrTrama, FALSE);
1764                return (FALSE);
1765        }
1766        respuestaConsola(socket_c, ptrTrama, TRUE);
1767        return (TRUE);
1768}
1769// ________________________________________________________________________________________________________
1770// Función: RESPUESTA_Reiniciar
1771//
1772//      Descripción:
1773//              Respuesta del cliente al comando Reiniciar
1774//      Parámetros:
1775//              - socket_c: Socket del cliente que envió el mensaje
1776//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1777//      Devuelve:
1778//              TRUE: Si el proceso es correcto
1779//              FALSE: En caso de ocurrir algún error
1780// ________________________________________________________________________________________________________
1781BOOLEAN RESPUESTA_Reiniciar(SOCKET *socket_c, TRAMA* ptrTrama) {
1782        char msglog[LONSTD];
1783        Database db;
1784        Table tbl;
1785        int i;
1786        char *iph, *ido;
1787        char modulo[] = "RESPUESTA_Reiniciar()";
1788
1789        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1790                errorLog(modulo, 20, FALSE);
1791                db.GetErrorErrStr(msglog);
1792                errorInfo(modulo, msglog);
1793                return (FALSE);
1794        }
1795
1796        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1797        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1798
1799        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1800                liberaMemoria(iph);
1801                liberaMemoria(ido);
1802                errorLog(modulo, 30, FALSE);
1803                return (FALSE); // Error al registrar notificacion
1804        }
1805
1806        if (clienteExistente(iph, &i)) // Actualiza estado
1807                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
1808       
1809        liberaMemoria(iph);
1810        liberaMemoria(ido);
1811
1812        db.Close(); // Cierra conexión
1813        return (TRUE);
1814}
1815// ________________________________________________________________________________________________________
1816// Función: IniciarSesion
1817//
1818//      Descripción:
1819//              Procesa el comando Iniciar Sesión
1820//      Parámetros:
1821//              - socket_c: Socket de la consola al envió el mensaje
1822//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1823//      Devuelve:
1824//              TRUE: Si el proceso es correcto
1825//              FALSE: En caso de ocurrir algún error
1826// ________________________________________________________________________________________________________
1827BOOLEAN IniciarSesion(SOCKET *socket_c, TRAMA* ptrTrama) {
1828        char msglog[LONSTD];
1829        char modulo[] = "IniciarSesion()";
1830
1831        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1832                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1833                errorInfo(modulo, msglog);
1834                respuestaConsola(socket_c, ptrTrama, FALSE);
1835                return (FALSE);
1836        }
1837        respuestaConsola(socket_c, ptrTrama, TRUE);
1838        return (TRUE);
1839}
1840// ________________________________________________________________________________________________________
1841// Función: RESPUESTA_IniciarSesion
1842//
1843//      Descripción:
1844//              Respuesta del cliente al comando Iniciar Sesión
1845//      Parámetros:
1846//              - socket_c: Socket del cliente que envió el mensaje
1847//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1848//      Devuelve:
1849//              TRUE: Si el proceso es correcto
1850//              FALSE: En caso de ocurrir algún error
1851// ________________________________________________________________________________________________________
1852BOOLEAN RESPUESTA_IniciarSesion(SOCKET *socket_c, TRAMA* ptrTrama) {
1853        char msglog[LONSTD];
1854        Database db;
1855        Table tbl;
1856        int i;
1857        char *iph, *ido;
1858        char modulo[] = "RESPUESTA_IniciarSesion()";
1859
1860        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1861                errorLog(modulo, 20, FALSE);
1862                db.GetErrorErrStr(msglog);
1863                errorInfo(modulo, msglog);
1864                return (FALSE);
1865        }
1866
1867        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1868        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1869
1870        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1871                liberaMemoria(iph);
1872                liberaMemoria(ido);
1873                errorLog(modulo, 30, FALSE);
1874                return (FALSE); // Error al registrar notificacion
1875        }
1876
1877        if (clienteExistente(iph, &i)) // Actualiza estado
1878                strcpy(tbsockets[i].estado, CLIENTE_APAGADO);
1879               
1880        liberaMemoria(iph);
1881        liberaMemoria(ido);
1882               
1883        db.Close(); // Cierra conexión
1884        return (TRUE);
1885}
1886// ________________________________________________________________________________________________________
1887// Función: CrearImagen
1888//
1889//      Descripción:
1890//              Crea una imagen de una partición de un disco y la guarda o bien en un repositorio
1891//      Parámetros:
1892//              - socket_c: Socket de la consola al envió el mensaje
1893//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1894//      Devuelve:
1895//              TRUE: Si el proceso es correcto
1896//              FALSE: En caso de ocurrir algún error
1897// ________________________________________________________________________________________________________
1898BOOLEAN CrearImagen(SOCKET *socket_c, TRAMA* ptrTrama) {
1899        char msglog[LONSTD];
1900        char modulo[] = "CrearImagen()";
1901
1902        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
1903                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
1904                errorInfo(modulo, msglog);
1905                respuestaConsola(socket_c, ptrTrama, FALSE);
1906                return (FALSE);
1907        }
1908        respuestaConsola(socket_c, ptrTrama, TRUE);
1909        return (TRUE);
1910}
1911// ________________________________________________________________________________________________________
1912// Función: RESPUESTA_CrearImagen
1913//
1914//      Descripción:
1915//              Respuesta del cliente al comando CrearImagen
1916//      Parámetros:
1917//              - socket_c: Socket del cliente que envió el mensaje
1918//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
1919//      Devuelve:
1920//              TRUE: Si el proceso es correcto
1921//              FALSE: En caso de ocurrir algún error
1922// ________________________________________________________________________________________________________
1923BOOLEAN RESPUESTA_CrearImagen(SOCKET *socket_c, TRAMA* ptrTrama)
1924{
1925        char msglog[LONSTD];
1926        Database db;
1927        Table tbl;
1928        char *iph, *dsk, *par, *cpt, *ipr, *ido;
1929        char *idi;
1930        BOOLEAN res;
1931        char modulo[] = "RESPUESTA_CrearImagen()";
1932
1933        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
1934                errorLog(modulo, 20, FALSE);
1935                db.GetErrorErrStr(msglog);
1936                errorInfo(modulo, msglog);
1937                return (FALSE);
1938        }
1939
1940        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
1941        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
1942
1943        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
1944                liberaMemoria(iph);
1945                liberaMemoria(ido);
1946                errorLog(modulo, 30, FALSE);
1947                return (FALSE); // Error al registrar notificacion
1948        }
1949
1950        // Acciones posteriores
1951        idi = copiaParametro("idi",ptrTrama);
1952        dsk = copiaParametro("dsk",ptrTrama);
1953        par = copiaParametro("par",ptrTrama);
1954        cpt = copiaParametro("cpt",ptrTrama);
1955        ipr = copiaParametro("ipr",ptrTrama);
1956
1957        res=actualizaCreacionImagen(db, tbl, idi, dsk, par, cpt, ipr, ido);
1958
1959        liberaMemoria(idi);
1960        liberaMemoria(par);
1961        liberaMemoria(cpt);
1962        liberaMemoria(ipr);
1963       
1964        if(!res){
1965                errorLog(modulo, 94, FALSE);
1966                db.Close(); // Cierra conexión
1967                return (FALSE);
1968        }
1969
1970        db.Close(); // Cierra conexión
1971        return (TRUE);
1972}
1973// ________________________________________________________________________________________________________
1974// Función: actualizaCreacionImagen
1975//
1976//      Descripción:
1977//              Esta función actualiza la base de datos con el resultado de la creación de una imagen
1978//      Parámetros:
1979//              - db: Objeto base de datos (ya operativo)
1980//              - tbl: Objeto tabla
1981//              - idi: Identificador de la imagen
1982//              - dsk: Disco de donde se creó
1983//              - par: Partición de donde se creó
1984//              - cpt: Código de partición
1985//              - ipr: Ip del repositorio
1986//              - ido: Identificador del ordenador modelo
1987//      Devuelve:
1988//              TRUE: Si el proceso es correcto
1989//              FALSE: En caso de ocurrir algún error
1990// ________________________________________________________________________________________________________
1991BOOLEAN actualizaCreacionImagen(Database db, Table tbl, char* idi, char* dsk,
1992        char* par, char* cpt, char* ipr, char *ido) {
1993        char msglog[LONSTD], sqlstr[LONSQL];
1994        char modulo[] = "actualizaCreacionImagen()";
1995        int idr,ifs;
1996
1997        /* Toma identificador del repositorio correspondiente al ordenador modelo */
1998        snprintf(sqlstr, LONSQL,
1999                        "SELECT repositorios.idrepositorio"
2000                        "  FROM repositorios"
2001                        "  LEFT JOIN ordenadores USING (idrepositorio)"
2002                        " WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s", ipr, ido);
2003
2004        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2005                errorLog(modulo, 21, FALSE);
2006                db.GetErrorErrStr(msglog);
2007                errorInfo(modulo, msglog);
2008                return (FALSE);
2009        }
2010        if (!tbl.Get("idrepositorio", idr)) { // Toma dato
2011                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2012                errorInfo(modulo, msglog);
2013                return (FALSE);
2014        }
2015
2016        /* Toma identificador del perfilsoftware */
2017        snprintf(sqlstr, LONSQL,
2018                        "SELECT idperfilsoft"
2019                        "  FROM ordenadores_particiones"
2020                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", ido, dsk, par);
2021
2022        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2023                errorLog(modulo, 21, FALSE);
2024                db.GetErrorErrStr(msglog);
2025                errorInfo(modulo, msglog);
2026                return (FALSE);
2027        }
2028        if (!tbl.Get("idperfilsoft", ifs)) { // Toma dato
2029                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2030                errorInfo(modulo, msglog);
2031                return (FALSE);
2032        }
2033
2034        /* Actualizar los datos de la imagen */
2035        snprintf(sqlstr, LONSQL,
2036                        "UPDATE imagenes"
2037                        "   SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s, idperfilsoft=%d, idrepositorio=%d, fechacreacion=NOW()"
2038                        " WHERE idimagen=%s", ido, dsk, par, cpt, ifs, idr, idi);
2039
2040        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
2041                errorLog(modulo, 21, FALSE);
2042                db.GetErrorErrStr(msglog);
2043                errorInfo(modulo, msglog);
2044                return (FALSE);
2045        }
2046        return (TRUE);
2047}
2048// ________________________________________________________________________________________________________
2049// Función: CrearImagenBasica
2050//
2051//      Descripción:
2052//              Crea una imagen basica usando sincronización
2053//      Parámetros:
2054//              - socket_c: Socket de la consola al envió el mensaje
2055//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2056//      Devuelve:
2057//              TRUE: Si el proceso es correcto
2058//              FALSE: En caso de ocurrir algún error
2059// ________________________________________________________________________________________________________
2060BOOLEAN CrearImagenBasica(SOCKET *socket_c, TRAMA* ptrTrama) {
2061        char msglog[LONSTD];
2062        char modulo[] = "CrearImagenBasica()";
2063
2064        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2065                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2066                errorInfo(modulo, msglog);
2067                respuestaConsola(socket_c, ptrTrama, FALSE);
2068                return (FALSE);
2069        }
2070        respuestaConsola(socket_c, ptrTrama, TRUE);
2071        return (TRUE);
2072}
2073// ________________________________________________________________________________________________________
2074// Función: RESPUESTA_CrearImagenBasica
2075//
2076//      Descripción:
2077//              Respuesta del cliente al comando CrearImagenBasica
2078//      Parámetros:
2079//              - socket_c: Socket del cliente que envió el mensaje
2080//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2081//      Devuelve:
2082//              TRUE: Si el proceso es correcto
2083//              FALSE: En caso de ocurrir algún error
2084// ________________________________________________________________________________________________________
2085BOOLEAN RESPUESTA_CrearImagenBasica(SOCKET *socket_c, TRAMA* ptrTrama) {
2086        return(RESPUESTA_CrearImagen(socket_c,ptrTrama)); // La misma respuesta que la creación de imagen monolítica
2087}
2088// ________________________________________________________________________________________________________
2089// Función: CrearSoftIncremental
2090//
2091//      Descripción:
2092//              Crea una imagen incremental entre una partición de un disco y una imagen ya creada guardandola en el
2093//              mismo repositorio y en la misma carpeta donde está la imagen básica
2094//      Parámetros:
2095//              - socket_c: Socket de la consola al envió el mensaje
2096//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2097//      Devuelve:
2098//              TRUE: Si el proceso es correcto
2099//              FALSE: En caso de ocurrir algún error
2100// ________________________________________________________________________________________________________
2101BOOLEAN CrearSoftIncremental(SOCKET *socket_c, TRAMA* ptrTrama) {
2102        char msglog[LONSTD];
2103        char modulo[] = "CrearSoftIncremental()";
2104
2105        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2106                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2107                errorInfo(modulo, msglog);
2108                respuestaConsola(socket_c, ptrTrama, FALSE);
2109                return (FALSE);
2110        }
2111        respuestaConsola(socket_c, ptrTrama, TRUE);
2112        return (TRUE);
2113}
2114// ________________________________________________________________________________________________________
2115// Función: RESPUESTA_CrearSoftIncremental
2116//
2117//      Descripción:
2118//              Respuesta del cliente al comando crearImagenDiferencial
2119//      Parámetros:
2120//              - socket_c: Socket del cliente que envió el mensaje
2121//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2122//      Devuelve:
2123//              TRUE: Si el proceso es correcto
2124//              FALSE: En caso de ocurrir algún error
2125// ________________________________________________________________________________________________________
2126BOOLEAN RESPUESTA_CrearSoftIncremental(SOCKET *socket_c, TRAMA* ptrTrama)
2127{
2128        Database db;
2129        Table tbl;
2130        char *iph,*par,*ido,*idf;
2131        int ifs;
2132        char msglog[LONSTD],sqlstr[LONSQL];
2133        char modulo[] = "RESPUESTA_CrearSoftIncremental()";
2134
2135        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
2136                errorLog(modulo, 20, FALSE);
2137                db.GetErrorErrStr(msglog);
2138                errorInfo(modulo, msglog);
2139                return (FALSE);
2140        }
2141
2142        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2143        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2144
2145        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
2146                liberaMemoria(iph);
2147                liberaMemoria(ido);     
2148                errorLog(modulo, 30, FALSE);
2149                return (FALSE); // Error al registrar notificacion
2150        }
2151
2152        par = copiaParametro("par",ptrTrama);
2153
2154        /* Toma identificador del perfilsoftware creado por el inventario de software */
2155        sprintf(sqlstr,"SELECT idperfilsoft FROM ordenadores_particiones WHERE idordenador=%s AND numpar=%s",ido,par);
2156       
2157        liberaMemoria(iph);
2158        liberaMemoria(ido);     
2159        liberaMemoria(par);     
2160               
2161        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2162                errorLog(modulo, 21, FALSE);
2163                db.GetErrorErrStr(msglog);
2164                errorInfo(modulo, msglog);
2165                return (FALSE);
2166        }
2167        if (!tbl.Get("idperfilsoft", ifs)) { // Toma dato
2168                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2169                errorInfo(modulo, msglog);
2170                return (FALSE);
2171        }
2172
2173        /* Actualizar los datos de la imagen */
2174        idf = copiaParametro("idf",ptrTrama);
2175        sprintf(sqlstr,"UPDATE imagenes SET idperfilsoft=%d WHERE idimagen=%s",ifs,idf);
2176        liberaMemoria(idf);     
2177       
2178        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
2179                errorLog(modulo, 21, FALSE);
2180                db.GetErrorErrStr(msglog);
2181                errorInfo(modulo, msglog);
2182                return (FALSE);
2183        }
2184        db.Close(); // Cierra conexión
2185        return (TRUE);
2186}
2187// ________________________________________________________________________________________________________
2188// Función: actualizaCreacionSoftIncremental
2189//
2190//      Descripción:
2191//              Esta función actualiza la base de datos con el resultado de la creación de software incremental
2192//      Parámetros:
2193//              - db: Objeto base de datos (ya operativo)
2194//              - tbl: Objeto tabla
2195//              - idi: Identificador de la imagen
2196//              - idf: Identificador del software incremental
2197//      Devuelve:
2198//              TRUE: Si el proceso es correcto
2199//              FALSE: En caso de ocurrir algún error
2200// ________________________________________________________________________________________________________
2201BOOLEAN actualizaCreacionSoftIncremental(Database db, Table tbl, char* idi,char* idf)
2202{
2203        char msglog[LONSTD], sqlstr[LONSQL];
2204        char modulo[] = "actualizaCreacionSoftIncremental()";
2205
2206
2207        /* Comprueba si existe ya relación entre la imagen y el software incremental */
2208        sprintf(sqlstr, "SELECT * FROM imagenes_softincremental"
2209                                        " WHERE idimagen=%s AND idsoftincremental=%s", idi,idf);
2210
2211        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2212                errorLog(modulo, 21, FALSE);
2213                db.GetErrorErrStr(msglog);
2214                errorInfo(modulo, msglog);
2215                return (FALSE);
2216        }
2217        if (!tbl.ISEOF())
2218                return (TRUE); // Ya existe relación
2219
2220        // Crea relación entre la imagen y el software incremental
2221        sprintf(sqlstr,"INSERT INTO imagenes_softincremental (idimagen,idsoftincremental) VALUES (%s,%s)",idi,idf);
2222        if (!db.Execute(sqlstr, tbl)) { // Error al ejecutar la sentencia
2223                errorLog(modulo, 21, FALSE);
2224                db.GetErrorErrStr(msglog);
2225                errorInfo(modulo, msglog);
2226                return (FALSE);
2227        }
2228        return (TRUE);
2229}
2230// ________________________________________________________________________________________________________
2231// Función: RestaurarImagen
2232//
2233//      Descripción:
2234//              Restaura una imagen en una partición
2235//      Parámetros:
2236//              - socket_c: Socket de la consola al envió el mensaje
2237//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2238//      Devuelve:
2239//              TRUE: Si el proceso es correcto
2240//              FALSE: En caso de ocurrir algún error
2241// ________________________________________________________________________________________________________
2242BOOLEAN RestaurarImagen(SOCKET *socket_c, TRAMA* ptrTrama) {
2243        char msglog[LONSTD];
2244        char modulo[] = "RestaurarImagen()";
2245
2246        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2247                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2248                errorInfo(modulo, msglog);
2249                respuestaConsola(socket_c, ptrTrama, FALSE);
2250                return (FALSE);
2251        }
2252        respuestaConsola(socket_c, ptrTrama, TRUE);
2253        return (TRUE);
2254}
2255// ________________________________________________________________________________________________________
2256// Función: RestaurarImagenBasica
2257//
2258//      Descripción:
2259//              Restaura una imagen básica en una partición
2260//      Parámetros:
2261//              - socket_c: Socket de la consola al envió el mensaje
2262//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2263//      Devuelve:
2264//              TRUE: Si el proceso es correcto
2265//              FALSE: En caso de ocurrir algún error
2266// ________________________________________________________________________________________________________
2267BOOLEAN RestaurarImagenBasica(SOCKET *socket_c, TRAMA* ptrTrama) {
2268        char msglog[LONSTD];
2269        char modulo[] = "RestaurarImagenBasica()";
2270
2271        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2272                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2273                errorInfo(modulo, msglog);
2274                respuestaConsola(socket_c, ptrTrama, FALSE);
2275                return (FALSE);
2276        }
2277        respuestaConsola(socket_c, ptrTrama, TRUE);
2278        return (TRUE);
2279}
2280// ________________________________________________________________________________________________________
2281// Función: RestaurarSoftIncremental
2282//
2283//      Descripción:
2284//              Restaura una imagen básica junto con software incremental en una partición
2285//      Parámetros:
2286//              - socket_c: Socket de la consola al envió el mensaje
2287//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2288//      Devuelve:
2289//              TRUE: Si el proceso es correcto
2290//              FALSE: En caso de ocurrir algún error
2291// ________________________________________________________________________________________________________
2292BOOLEAN RestaurarSoftIncremental(SOCKET *socket_c, TRAMA* ptrTrama) {
2293        char msglog[LONSTD];
2294        char modulo[] = "RestaurarSoftIncremental()";
2295
2296        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2297                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2298                errorInfo(modulo, msglog);
2299                respuestaConsola(socket_c, ptrTrama, FALSE);
2300                return (FALSE);
2301        }
2302        respuestaConsola(socket_c, ptrTrama, TRUE);
2303        return (TRUE);
2304}
2305// ________________________________________________________________________________________________________
2306// Función: RESPUESTA_RestaurarImagen
2307//
2308//      Descripción:
2309//              Respuesta del cliente al comando RestaurarImagen
2310//      Parámetros:
2311//              - socket_c: Socket del cliente que envió el mensaje
2312//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2313//      Devuelve:
2314//              TRUE: Si el proceso es correcto
2315//              FALSE: En caso de ocurrir algún error
2316// ________________________________________________________________________________________________________
2317//
2318BOOLEAN RESPUESTA_RestaurarImagen(SOCKET *socket_c, TRAMA* ptrTrama)
2319{
2320        char msglog[LONSTD];
2321        Database db;
2322        Table tbl;
2323        BOOLEAN res;
2324        char *iph, *ido, *idi, *dsk, *par, *ifs;
2325        char modulo[] = "RESPUESTA_RestaurarImagen()";
2326
2327        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
2328                errorLog(modulo, 20, FALSE);
2329                db.GetErrorErrStr(msglog);
2330                errorInfo(modulo, msglog);
2331                return (FALSE);
2332        }
2333
2334        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2335        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2336
2337        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
2338                liberaMemoria(iph);
2339                liberaMemoria(ido);     
2340                errorLog(modulo, 30, FALSE);
2341                return (FALSE); // Error al registrar notificacion
2342        }
2343
2344        // Acciones posteriores
2345        idi = copiaParametro("idi",ptrTrama); // Toma identificador de la imagen
2346        dsk = copiaParametro("dsk",ptrTrama); // Número de disco
2347        par = copiaParametro("par",ptrTrama); // Número de partición
2348        ifs = copiaParametro("ifs",ptrTrama); // Identificador del perfil software contenido
2349       
2350        res=actualizaRestauracionImagen(db, tbl, idi, dsk, par, ido, ifs);
2351       
2352        liberaMemoria(iph);
2353        liberaMemoria(ido);     
2354        liberaMemoria(idi);
2355        liberaMemoria(par);
2356        liberaMemoria(ifs);
2357
2358        if(!res){
2359                errorLog(modulo, 95, FALSE);
2360                db.Close(); // Cierra conexión
2361                return (FALSE);
2362        }
2363
2364        db.Close(); // Cierra conexión
2365        return (TRUE);
2366}
2367// ________________________________________________________________________________________________________
2368//
2369// Función: RESPUESTA_RestaurarImagenBasica
2370//
2371//      Descripción:
2372//              Respuesta del cliente al comando RestaurarImagen
2373//      Parámetros:
2374//              - socket_c: Socket del cliente que envió el mensaje
2375//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2376//      Devuelve:
2377//              TRUE: Si el proceso es correcto
2378//              FALSE: En caso de ocurrir algún error
2379// ________________________________________________________________________________________________________
2380//
2381BOOLEAN RESPUESTA_RestaurarImagenBasica(SOCKET *socket_c, TRAMA* ptrTrama) {
2382        return(RESPUESTA_RestaurarImagen(socket_c,ptrTrama));
2383}
2384// ________________________________________________________________________________________________________
2385// Función: RESPUESTA_RestaurarSoftIncremental
2386//
2387//      Descripción:
2388//              Respuesta del cliente al comando RestaurarSoftIncremental
2389//      Parámetros:
2390//              - socket_c: Socket del cliente que envió el mensaje
2391//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2392//      Devuelve:
2393//              TRUE: Si el proceso es correcto
2394//              FALSE: En caso de ocurrir algún error
2395// ________________________________________________________________________________________________________
2396BOOLEAN RESPUESTA_RestaurarSoftIncremental(SOCKET *socket_c, TRAMA* ptrTrama) {
2397        return(RESPUESTA_RestaurarImagen(socket_c,ptrTrama));
2398}
2399// ________________________________________________________________________________________________________
2400// Función: actualizaRestauracionImagen
2401//
2402//      Descripción:
2403//              Esta función actualiza la base de datos con el resultado de la restauración de una imagen
2404//      Parámetros:
2405//              - db: Objeto base de datos (ya operativo)
2406//              - tbl: Objeto tabla
2407//              - idi: Identificador de la imagen
2408//              - dsk: Disco de donde se restauró
2409//              - par: Partición de donde se restauró
2410//              - ido: Identificador del cliente donde se restauró
2411//              - ifs: Identificador del perfil software contenido      en la imagen
2412//      Devuelve:
2413//              TRUE: Si el proceso es correcto
2414//              FALSE: En caso de ocurrir algún error
2415// ________________________________________________________________________________________________________
2416BOOLEAN actualizaRestauracionImagen(Database db, Table tbl, char* idi,
2417        char* dsk, char* par, char* ido, char* ifs) {
2418        char msglog[LONSTD], sqlstr[LONSQL];
2419        char modulo[] = "actualizaRestauracionImagen()";
2420
2421        /* Actualizar los datos de la imagen */
2422        snprintf(sqlstr, LONSQL,
2423                        "UPDATE ordenadores_particiones"
2424                        "   SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW()"
2425                        " WHERE idordenador=%s AND numdisk=%s AND numpar=%s", idi, ifs, ido, dsk, par);
2426
2427        if (!db.Execute(sqlstr, tbl)) { // Error al recuperar los datos
2428                errorLog(modulo, 21, FALSE);
2429                db.GetErrorErrStr(msglog);
2430                errorInfo(modulo, msglog);
2431                return (FALSE);
2432        }
2433        return (TRUE);
2434}
2435// ________________________________________________________________________________________________________
2436// Función: Configurar
2437//
2438//      Descripción:
2439//              Configura la tabla de particiones
2440//      Parámetros:
2441//              - socket_c: Socket de la consola al envió el mensaje
2442//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2443//      Devuelve:
2444//              TRUE: Si el proceso es correcto
2445//              FALSE: En caso de ocurrir algún error
2446// ________________________________________________________________________________________________________
2447BOOLEAN Configurar(SOCKET *socket_c, TRAMA* ptrTrama) {
2448        char msglog[LONSTD];
2449        char modulo[] = "Configurar()";
2450
2451        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2452                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2453                errorInfo(modulo, msglog);
2454                respuestaConsola(socket_c, ptrTrama, FALSE);
2455                return (FALSE);
2456        }
2457        respuestaConsola(socket_c, ptrTrama, TRUE);
2458        return (TRUE);
2459}
2460// ________________________________________________________________________________________________________
2461// Función: RESPUESTA_Configurar
2462//
2463//      Descripción:
2464//              Respuesta del cliente al comando Configurar
2465//      Parámetros:
2466//              - socket_c: Socket del cliente que envió el mensaje
2467//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2468//      Devuelve:
2469//              TRUE: Si el proceso es correcto
2470//              FALSE: En caso de ocurrir algún error
2471// ________________________________________________________________________________________________________
2472//
2473BOOLEAN RESPUESTA_Configurar(SOCKET *socket_c, TRAMA* ptrTrama)
2474{
2475        char msglog[LONSTD];
2476        Database db;
2477        Table tbl;
2478        BOOLEAN res;
2479        char *iph, *ido,*cfg;
2480        char modulo[] = "RESPUESTA_Configurar()";
2481
2482        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
2483                errorLog(modulo, 20, FALSE);
2484                db.GetErrorErrStr(msglog);
2485                errorInfo(modulo, msglog);
2486                return (FALSE);
2487        }
2488
2489        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2490        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2491
2492        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
2493                liberaMemoria(iph);
2494                liberaMemoria(ido);     
2495                errorLog(modulo, 30, FALSE);
2496                return (FALSE); // Error al registrar notificacion
2497        }
2498
2499        cfg = copiaParametro("cfg",ptrTrama); // Toma configuración de particiones
2500        res=actualizaConfiguracion(db, tbl, cfg, atoi(ido)); // Actualiza la configuración del ordenador
2501       
2502        liberaMemoria(iph);
2503        liberaMemoria(ido);     
2504        liberaMemoria(cfg);     
2505               
2506        if(!res){       
2507                errorLog(modulo, 24, FALSE);
2508                return (FALSE); // Error al registrar notificacion
2509        }
2510       
2511        db.Close(); // Cierra conexión
2512        return (TRUE);
2513}
2514// ________________________________________________________________________________________________________
2515// Función: EjecutarScript
2516//
2517//      Descripción:
2518//              Ejecuta un script de código
2519//      Parámetros:
2520//              - socket_c: Socket de la consola al envió el mensaje
2521//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2522//      Devuelve:
2523//              TRUE: Si el proceso es correcto
2524//              FALSE: En caso de ocurrir algún error
2525// ________________________________________________________________________________________________________
2526BOOLEAN EjecutarScript(SOCKET *socket_c, TRAMA* ptrTrama) {
2527        char msglog[LONSTD];
2528        char modulo[] = "EjecutarScript()";
2529
2530        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2531                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2532                errorInfo(modulo, msglog);
2533                respuestaConsola(socket_c, ptrTrama, FALSE);
2534                return (FALSE);
2535        }
2536        respuestaConsola(socket_c, ptrTrama, TRUE);
2537        return (TRUE);
2538}
2539// ________________________________________________________________________________________________________
2540// Función: RESPUESTA_EjecutarScript
2541//
2542//      Descripción:
2543//              Respuesta del cliente al comando EjecutarScript
2544//      Parámetros:
2545//              - socket_c: Socket del cliente que envió el mensaje
2546//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2547//      Devuelve:
2548//              TRUE: Si el proceso es correcto
2549//              FALSE: En caso de ocurrir algún error
2550// ________________________________________________________________________________________________________
2551BOOLEAN RESPUESTA_EjecutarScript(SOCKET *socket_c, TRAMA* ptrTrama)
2552{
2553        char msglog[LONSTD];
2554        Database db;
2555        Table tbl;
2556        char *iph, *ido,*cfg;
2557        int res;
2558
2559        char modulo[] = "RESPUESTA_EjecutarScript()";
2560
2561        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
2562                errorLog(modulo, 20, FALSE);
2563                db.GetErrorErrStr(msglog);
2564                errorInfo(modulo, msglog);
2565                return (FALSE);
2566        }
2567
2568        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
2569        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
2570
2571        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
2572                liberaMemoria(iph);
2573                liberaMemoria(ido);     
2574                errorLog(modulo, 30, FALSE);
2575                return (FALSE); // Error al registrar notificacion
2576        }
2577       
2578        cfg = copiaParametro("cfg",ptrTrama); // Toma configuración de particiones
2579       
2580        if(cfg){
2581                res=actualizaConfiguracion(db, tbl, cfg, atoi(ido)); // Actualiza la configuración del ordenador
2582                liberaMemoria(cfg);     
2583        }
2584
2585        liberaMemoria(iph);
2586        liberaMemoria(ido);
2587
2588       
2589        db.Close(); // Cierra conexión
2590        return (TRUE);
2591}
2592// ________________________________________________________________________________________________________
2593// Función: InventarioHardware
2594//
2595//      Descripción:
2596//              Solicita al cliente un inventario de su hardware
2597//      Parámetros:
2598//              - socket_c: Socket de la consola al envió el mensaje
2599//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2600//      Devuelve:
2601//              TRUE: Si el proceso es correcto
2602//              FALSE: En caso de ocurrir algún error
2603// ________________________________________________________________________________________________________
2604BOOLEAN InventarioHardware(SOCKET *socket_c, TRAMA* ptrTrama) {
2605        char msglog[LONSTD];
2606        char modulo[] = "InventarioHardware()";
2607
2608        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2609                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2610                errorInfo(modulo, msglog);
2611                respuestaConsola(socket_c, ptrTrama, FALSE);
2612                return (FALSE);
2613        }
2614        respuestaConsola(socket_c, ptrTrama, TRUE);
2615        return (TRUE);
2616}
2617// ________________________________________________________________________________________________________
2618// Función: RESPUESTA_InventarioHardware
2619//
2620//      Descripción:
2621//              Respuesta del cliente al comando InventarioHardware
2622//      Parámetros:
2623//              - socket_c: Socket del cliente que envió el mensaje
2624//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2625//      Devuelve:
2626//              TRUE: Si el proceso es correcto
2627//              FALSE: En caso de ocurrir algún error
2628// ________________________________________________________________________________________________________
2629BOOLEAN RESPUESTA_InventarioHardware(SOCKET *socket_c, TRAMA* ptrTrama) {
2630        char msglog[LONSTD];
2631        Database db;
2632        Table tbl;
2633        BOOLEAN res;
2634        char *iph, *ido, *idc, *npc, *hrd, *buffer;
2635        char modulo[] = "RESPUESTA_InventarioHardware()";
2636
2637        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
2638                errorLog(modulo, 20, FALSE);
2639                db.GetErrorErrStr(msglog);
2640                errorInfo(modulo, msglog);
2641                return (FALSE);
2642        }
2643
2644        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip del cliente
2645        ido = copiaParametro("ido",ptrTrama); // Toma identificador del cliente
2646
2647        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
2648                liberaMemoria(iph);
2649                liberaMemoria(ido);     
2650                errorLog(modulo, 30, FALSE);
2651                return (FALSE); // Error al registrar notificacion
2652        }
2653        // Lee archivo de inventario enviado anteriormente
2654        hrd = copiaParametro("hrd",ptrTrama);
2655        buffer = rTrim(leeArchivo(hrd));
2656       
2657        npc = copiaParametro("npc",ptrTrama);
2658        idc = copiaParametro("idc",ptrTrama); // Toma identificador del Centro
2659       
2660        if (buffer)
2661                res=actualizaHardware(db, tbl, buffer, ido, npc, idc);
2662       
2663        liberaMemoria(iph);
2664        liberaMemoria(ido);                     
2665        liberaMemoria(npc);                     
2666        liberaMemoria(idc);             
2667        liberaMemoria(buffer);         
2668       
2669        if(!res){
2670                errorLog(modulo, 53, FALSE);
2671                return (FALSE);
2672        }
2673               
2674        db.Close(); // Cierra conexión
2675        return (TRUE);
2676}
2677// ________________________________________________________________________________________________________
2678// Función: actualizaHardware
2679//
2680//              Descripción:
2681//                      Actualiza la base de datos con la configuracion hardware del cliente
2682//              Parámetros:
2683//                      - db: Objeto base de datos (ya operativo)
2684//                      - tbl: Objeto tabla
2685//                      - hrd: cadena con el inventario hardware
2686//                      - ido: Identificador del ordenador
2687//                      - npc: Nombre del ordenador
2688//                      - idc: Identificador del centro o Unidad organizativa
2689// ________________________________________________________________________________________________________
2690//
2691BOOLEAN actualizaHardware(Database db, Table tbl, char* hrd, char*ido,char* npc, char *idc)
2692{
2693        char msglog[LONSTD], sqlstr[LONSQL];
2694        int idtipohardware, idperfilhard;
2695        int lon, i, j, aux;
2696        bool retval;
2697        char *whard;
2698        int tbidhardware[MAXHARDWARE];
2699        char *tbHardware[MAXHARDWARE],*dualHardware[2], descripcion[250], strInt[LONINT], *idhardwares;
2700        char modulo[] = "actualizaHardware()";
2701
2702        /* Toma Centro (Unidad Organizativa) */
2703        sprintf(sqlstr, "SELECT * FROM ordenadores WHERE idordenador=%s", ido);
2704
2705        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2706                errorLog(modulo, 21, FALSE);
2707                db.GetErrorErrStr(msglog);
2708                errorInfo(modulo, msglog);
2709                return (FALSE);
2710        }
2711        if (!tbl.Get("idperfilhard", idperfilhard)) { // Toma dato
2712                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2713                errorInfo(modulo, msglog);
2714                return (FALSE);
2715        }
2716        whard=escaparCadena(hrd); // Codificar comillas simples
2717        if(!whard)
2718                return (FALSE);
2719        /* Recorre componentes hardware*/
2720        lon = splitCadena(tbHardware, whard, '\n');
2721        if (lon > MAXHARDWARE)
2722                lon = MAXHARDWARE; // Limita el número de componentes hardware
2723        /*
2724         for (i=0;i<lon;i++){
2725         sprintf(msglog,"Linea de inventario: %s",tbHardware[i]);
2726         RegistraLog(msglog,FALSE);
2727         }
2728         */
2729        for (i = 0; i < lon; i++) {
2730                splitCadena(dualHardware, rTrim(tbHardware[i]), '=');
2731                //sprintf(msglog,"nemonico: %s",dualHardware[0]);
2732                //RegistraLog(msglog,FALSE);
2733                //sprintf(msglog,"valor: %s",dualHardware[1]);
2734                //RegistraLog(msglog,FALSE);
2735                sprintf(sqlstr, "SELECT idtipohardware,descripcion FROM tipohardwares "
2736                        " WHERE nemonico='%s'", dualHardware[0]);
2737                if (!db.Execute(sqlstr, tbl)) { // Error al leer
2738                        errorLog(modulo, 21, FALSE);
2739                        db.GetErrorErrStr(msglog);
2740                        errorInfo(modulo, msglog);
2741                        return (FALSE);
2742                }
2743                if (tbl.ISEOF()) { //  Tipo de Hardware NO existente
2744                        sprintf(msglog, "%s: %s)", tbErrores[54], dualHardware[0]);
2745                        errorInfo(modulo, msglog);
2746                        return (FALSE);
2747                } else { //  Tipo de Hardware Existe
2748                        if (!tbl.Get("idtipohardware", idtipohardware)) { // Toma dato
2749                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2750                                errorInfo(modulo, msglog);
2751                                return (FALSE);
2752                        }
2753                        if (!tbl.Get("descripcion", descripcion)) { // Toma dato
2754                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2755                                errorInfo(modulo, msglog);
2756                                return (FALSE);
2757                        }
2758
2759                        sprintf(sqlstr, "SELECT idhardware FROM hardwares "
2760                                " WHERE idtipohardware=%d AND descripcion='%s'",
2761                                        idtipohardware, dualHardware[1]);
2762
2763                        // Ejecuta consulta
2764                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2765                                errorLog(modulo, 21, FALSE);
2766                                db.GetErrorErrStr(msglog);
2767                                errorInfo(modulo, msglog);
2768                                return (FALSE);
2769                        }
2770
2771                        if (tbl.ISEOF()) { //  Hardware NO existente
2772                                sprintf(sqlstr, "INSERT hardwares (idtipohardware,descripcion,idcentro,grupoid) "
2773                                                        " VALUES(%d,'%s',%s,0)", idtipohardware,
2774                                                dualHardware[1], idc);
2775                                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2776                                        db.GetErrorErrStr(msglog); // Error al acceder al registro
2777                                        errorInfo(modulo, msglog);
2778                                        return (FALSE);
2779                                }
2780                                // Recupera el identificador del hardware
2781                                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
2782                                if (!db.Execute(sqlstr, tbl)) { // Error al leer
2783                                        errorLog(modulo, 21, FALSE);
2784                                        db.GetErrorErrStr(msglog);
2785                                        errorInfo(modulo, msglog);
2786                                        return (FALSE);
2787                                }
2788                                if (!tbl.ISEOF()) { // Si existe registro
2789                                        if (!tbl.Get("identificador", tbidhardware[i])) {
2790                                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2791                                                errorInfo(modulo, msglog);
2792                                                return (FALSE);
2793                                        }
2794                                }
2795                        } else {
2796                                if (!tbl.Get("idhardware", tbidhardware[i])) { // Toma dato
2797                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
2798                                        errorInfo(modulo, msglog);
2799                                        return (FALSE);
2800                                }
2801                        }
2802                }
2803        }
2804        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
2805
2806        for (i = 0; i < lon - 1; i++) {
2807                for (j = i + 1; j < lon; j++) {
2808                        if (tbidhardware[i] > tbidhardware[j]) {
2809                                aux = tbidhardware[i];
2810                                tbidhardware[i] = tbidhardware[j];
2811                                tbidhardware[j] = aux;
2812                        }
2813                }
2814        }
2815        /* Crea cadena de identificadores de componentes hardware separados por coma */
2816        sprintf(strInt, "%d", tbidhardware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
2817        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
2818        idhardwares = reservaMemoria(sizeof(aux) * lon + lon);
2819        if (idhardwares == NULL) {
2820                errorLog(modulo, 3, FALSE);
2821                return (FALSE);
2822        }
2823        aux = sprintf(idhardwares, "%d", tbidhardware[0]);
2824        for (i = 1; i < lon; i++)
2825                aux += sprintf(idhardwares + aux, ",%d", tbidhardware[i]);
2826
2827        if (!cuestionPerfilHardware(db, tbl, idc, ido, idperfilhard, idhardwares,
2828                        npc, tbidhardware, lon)) {
2829                errorLog(modulo, 55, FALSE);
2830                errorInfo(modulo, msglog);
2831                retval=FALSE;
2832        }
2833        else {
2834                retval=TRUE;
2835        }
2836        liberaMemoria(whard);
2837        liberaMemoria(idhardwares);
2838        return (retval);
2839}
2840// ________________________________________________________________________________________________________
2841// Función: cuestionPerfilHardware
2842//
2843//              Descripción:
2844//                      Comprueba existencia de perfil hardware y actualización de éste para el ordenador
2845//              Parámetros:
2846//                      - db: Objeto base de datos (ya operativo)
2847//                      - tbl: Objeto tabla
2848//                      - idc: Identificador de la Unidad organizativa donde se encuentra el cliente
2849//                      - ido: Identificador del ordenador
2850//                      - tbidhardware: Identificador del tipo de hardware
2851//                      - con: Número de componentes detectados para configurar un el perfil hardware
2852//                      - npc: Nombre del cliente
2853// ________________________________________________________________________________________________________
2854BOOLEAN cuestionPerfilHardware(Database db, Table tbl, char* idc, char* ido,
2855                int idperfilhardware, char*idhardwares, char *npc, int *tbidhardware,
2856                int lon)
2857{
2858        char msglog[LONSTD], *sqlstr;
2859        int i;
2860        int nwidperfilhard;
2861        char modulo[] = "cuestionPerfilHardware()";
2862
2863        sqlstr = reservaMemoria(strlen(idhardwares)+LONSQL); // Reserva para escribir sentencia SQL
2864        if (sqlstr == NULL) {
2865                errorLog(modulo, 3, FALSE);
2866                return (FALSE);
2867        }
2868        // Busca perfil hard del ordenador que contenga todos los componentes hardware encontrados
2869        sprintf(sqlstr, "SELECT idperfilhard FROM"
2870                " (SELECT perfileshard_hardwares.idperfilhard as idperfilhard,"
2871                "       group_concat(cast(perfileshard_hardwares.idhardware AS char( 11) )"
2872                "       ORDER BY perfileshard_hardwares.idhardware SEPARATOR ',' ) AS idhardwares"
2873                " FROM  perfileshard_hardwares"
2874                " GROUP BY perfileshard_hardwares.idperfilhard) AS temp"
2875                " WHERE idhardwares LIKE '%s'", idhardwares);
2876        // Ejecuta consulta
2877        if (!db.Execute(sqlstr, tbl)) { // Error al leer
2878                errorLog(modulo, 21, FALSE);
2879                db.GetErrorErrStr(msglog);
2880                errorInfo(modulo, msglog);
2881                liberaMemoria(sqlstr);
2882                return (false);
2883        }
2884        if (tbl.ISEOF()) { // No existe un perfil hardware con esos componentes de componentes hardware, lo crea
2885                sprintf(sqlstr, "INSERT perfileshard  (descripcion,idcentro,grupoid)"
2886                                " VALUES('Perfil hardware (%s) ',%s,0)", npc, idc);
2887                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2888                        db.GetErrorErrStr(msglog);
2889                        errorInfo(modulo, msglog);
2890                        liberaMemoria(sqlstr);
2891                        return (false);
2892                }
2893                // Recupera el identificador del nuevo perfil hardware
2894                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
2895                if (!db.Execute(sqlstr, tbl)) { // Error al leer
2896                        db.GetErrorErrStr(msglog);
2897                        errorInfo(modulo, msglog);
2898                        liberaMemoria(sqlstr);
2899                        return (false);
2900                }
2901                if (!tbl.ISEOF()) { // Si existe registro
2902                        if (!tbl.Get("identificador", nwidperfilhard)) {
2903                                tbl.GetErrorErrStr(msglog);
2904                                errorInfo(modulo, msglog);
2905                                liberaMemoria(sqlstr);
2906                                return (false);
2907                        }
2908                }
2909                // Crea la relación entre perfiles y componenetes hardware
2910                for (i = 0; i < lon; i++) {
2911                        sprintf(sqlstr, "INSERT perfileshard_hardwares  (idperfilhard,idhardware)"
2912                                                " VALUES(%d,%d)", nwidperfilhard, tbidhardware[i]);
2913                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2914                                db.GetErrorErrStr(msglog);
2915                                errorInfo(modulo, msglog);
2916                                liberaMemoria(sqlstr);
2917                                return (false);
2918                        }
2919                }
2920        } else { // Existe un perfil con todos esos componentes
2921                if (!tbl.Get("idperfilhard", nwidperfilhard)) {
2922                        tbl.GetErrorErrStr(msglog);
2923                        errorInfo(modulo, msglog);
2924                        liberaMemoria(sqlstr);
2925                        return (false);
2926                }
2927        }
2928        if (idperfilhardware != nwidperfilhard) { // No coinciden los perfiles
2929                // Actualiza el identificador del perfil hardware del ordenador
2930                sprintf(sqlstr, "UPDATE ordenadores SET idperfilhard=%d"
2931                        " WHERE idordenador=%s", nwidperfilhard, ido);
2932                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2933                        db.GetErrorErrStr(msglog);
2934                        errorInfo(modulo, msglog);
2935                        liberaMemoria(sqlstr);
2936                        return (false);
2937                }
2938        }
2939        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
2940        sprintf(sqlstr, "DELETE FROM perfileshard_hardwares WHERE idperfilhard IN "
2941                " (SELECT idperfilhard FROM perfileshard WHERE idperfilhard NOT IN"
2942                " (SELECT DISTINCT idperfilhard from ordenadores))");
2943        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2944                db.GetErrorErrStr(msglog);
2945                errorInfo(modulo, msglog);
2946                liberaMemoria(sqlstr);
2947                return (false);
2948        }
2949
2950        /* Eliminar Perfiles hardware que quedan húerfanos */
2951        sprintf(sqlstr, "DELETE FROM perfileshard WHERE idperfilhard NOT IN"
2952                        " (SELECT DISTINCT idperfilhard FROM ordenadores)");
2953        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2954                db.GetErrorErrStr(msglog);
2955                errorInfo(modulo, msglog);
2956                liberaMemoria(sqlstr);
2957                return (false);
2958        }
2959        /* Eliminar Relación de hardwares con Perfiles hardware que quedan húerfanos */
2960        sprintf(sqlstr, "DELETE FROM perfileshard_hardwares WHERE idperfilhard NOT IN"
2961                        " (SELECT idperfilhard FROM perfileshard)");
2962        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
2963                db.GetErrorErrStr(msglog);
2964                errorInfo(modulo, msglog);
2965                liberaMemoria(sqlstr);
2966                return (false);
2967        }
2968        liberaMemoria(sqlstr);
2969        return (TRUE);
2970}
2971// ________________________________________________________________________________________________________
2972// Función: InventarioSoftware
2973//
2974//      Descripción:
2975//              Solicita al cliente un inventario de su software
2976//      Parámetros:
2977//              - socket_c: Socket de la consola al envió el mensaje
2978//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
2979//      Devuelve:
2980//              TRUE: Si el proceso es correcto
2981//              FALSE: En caso de ocurrir algún error
2982// ________________________________________________________________________________________________________
2983BOOLEAN InventarioSoftware(SOCKET *socket_c, TRAMA* ptrTrama) {
2984        char msglog[LONSTD];
2985        char modulo[] = "InventarioSoftware()";
2986
2987        if (!enviaComando(ptrTrama, CLIENTE_OCUPADO)) {
2988                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
2989                errorInfo(modulo, msglog);
2990                respuestaConsola(socket_c, ptrTrama, FALSE);
2991                return (FALSE);
2992        }
2993        respuestaConsola(socket_c, ptrTrama, TRUE);
2994        return (TRUE);
2995}
2996// ________________________________________________________________________________________________________
2997// Función: RESPUESTA_InventarioSoftware
2998//
2999//      Descripción:
3000//              Respuesta del cliente al comando InventarioSoftware
3001//      Parámetros:
3002//              - socket_c: Socket del cliente que envió el mensaje
3003//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
3004//      Devuelve:
3005//              TRUE: Si el proceso es correcto
3006//              FALSE: En caso de ocurrir algún error
3007// ________________________________________________________________________________________________________
3008BOOLEAN RESPUESTA_InventarioSoftware(SOCKET *socket_c, TRAMA* ptrTrama) {
3009        char msglog[LONSTD];
3010        Database db;
3011        Table tbl;
3012        BOOLEAN res;
3013        char *iph, *ido, *npc, *idc, *par, *sft, *buffer;
3014        char modulo[] = "RESPUESTA_InventarioSoftware()";
3015
3016        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
3017                errorLog(modulo, 20, FALSE);
3018                db.GetErrorErrStr(msglog);
3019                errorInfo(modulo, msglog);
3020                return (FALSE);
3021        }
3022
3023        iph = copiaParametro("iph",ptrTrama); // Toma dirección ip
3024        ido = copiaParametro("ido",ptrTrama); // Toma identificador del ordenador
3025
3026        if (!respuestaEstandar(ptrTrama, iph, ido, db, tbl)) {
3027                liberaMemoria(iph);
3028                liberaMemoria(ido);     
3029                errorLog(modulo, 30, FALSE);
3030                return (FALSE); // Error al registrar notificacion
3031        }
3032       
3033        npc = copiaParametro("npc",ptrTrama);
3034        idc = copiaParametro("idc",ptrTrama); // Toma identificador del Centro 
3035        par = copiaParametro("par",ptrTrama);
3036        sft = copiaParametro("sft",ptrTrama);
3037
3038        buffer = rTrim(leeArchivo(sft));
3039        if (buffer)
3040                res=actualizaSoftware(db, tbl, buffer, par, ido, npc, idc);
3041
3042        liberaMemoria(iph);
3043        liberaMemoria(ido);     
3044        liberaMemoria(npc);     
3045        liberaMemoria(idc);     
3046        liberaMemoria(par);     
3047        liberaMemoria(sft);     
3048
3049        if(!res){
3050                errorLog(modulo, 82, FALSE);
3051                return (FALSE);
3052        }       
3053       
3054        db.Close(); // Cierra conexión
3055        return (TRUE);
3056}
3057// ________________________________________________________________________________________________________
3058// Función: actualizaSoftware
3059//
3060//      Descripción:
3061//              Actualiza la base de datos con la configuración software del cliente
3062//      Parámetros:
3063//              - db: Objeto base de datos (ya operativo)
3064//              - tbl: Objeto tabla
3065//              - sft: cadena con el inventario software
3066//              - par: Número de la partición
3067//              - ido: Identificador del ordenador del cliente en la tabla
3068//              - npc: Nombre del ordenador
3069//              - idc: Identificador del centro o Unidad organizativa
3070//      Devuelve:
3071//              TRUE: Si el proceso es correcto
3072//              FALSE: En caso de ocurrir algún error
3073// ________________________________________________________________________________________________________
3074BOOLEAN actualizaSoftware(Database db, Table tbl, char* sft, char* par,char* ido, char* npc, char* idc)
3075{
3076        int i, j, lon, aux, idperfilsoft;
3077        bool retval;
3078        char *wsft;
3079        int tbidsoftware[MAXSOFTWARE];
3080        char *tbSoftware[MAXSOFTWARE],msglog[LONSTD], sqlstr[LONSQL], strInt[LONINT], *idsoftwares;
3081        char modulo[] = "actualizaSoftware()";
3082
3083        /* Toma Centro (Unidad Organizativa) y perfil software */
3084        sprintf(sqlstr, "SELECT idperfilsoft,numpar"
3085                " FROM ordenadores_particiones"
3086                " WHERE idordenador=%s", ido);
3087
3088        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3089                errorLog(modulo, 21, FALSE);
3090                db.GetErrorErrStr(msglog);
3091                errorInfo(modulo, msglog);
3092                return (FALSE);
3093        }
3094        idperfilsoft = 0; // Por defecto se supone que el ordenador no tiene aún detectado el perfil software
3095        while (!tbl.ISEOF()) { // Recorre particiones
3096                if (!tbl.Get("numpar", aux)) {
3097                        tbl.GetErrorErrStr(msglog);
3098                        errorInfo(modulo, msglog);
3099                        return (FALSE);
3100                }
3101                if (aux == atoi(par)) { // Se encuentra la partición
3102                        if (!tbl.Get("idperfilsoft", idperfilsoft)) {
3103                                tbl.GetErrorErrStr(msglog);
3104                                errorInfo(modulo, msglog);
3105                                return (FALSE);
3106                        }
3107                        break;
3108                }
3109                tbl.MoveNext();
3110        }
3111        wsft=escaparCadena(sft); // Codificar comillas simples
3112        if(!wsft)
3113                return (FALSE);
3114
3115        /* Recorre componentes software*/
3116        lon = splitCadena(tbSoftware, wsft, '\n');
3117
3118        if (lon == 0)
3119                return (true); // No hay lineas que procesar
3120        if (lon > MAXSOFTWARE)
3121                lon = MAXSOFTWARE; // Limita el número de componentes software
3122
3123        for (i = 0; i < lon; i++) {
3124                sprintf(sqlstr,
3125                                "SELECT idsoftware FROM softwares WHERE descripcion ='%s'",
3126                                rTrim(tbSoftware[i]));
3127
3128                // Ejecuta consulta
3129                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3130                        errorLog(modulo, 21, FALSE);
3131                        db.GetErrorErrStr(msglog);
3132                        errorInfo(modulo, msglog);
3133                        return (FALSE);
3134                }
3135
3136                if (tbl.ISEOF()) { //  Software NO existente
3137                        sprintf(sqlstr, "INSERT INTO softwares (idtiposoftware,descripcion,idcentro,grupoid)"
3138                                                " VALUES(2,'%s',%s,0)", tbSoftware[i], idc);
3139
3140                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3141                                db.GetErrorErrStr(msglog); // Error al acceder al registro
3142                                errorInfo(modulo, msglog);
3143                                return (FALSE);
3144                        }
3145                        // Recupera el identificador del software
3146                        sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3147                        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3148                                db.GetErrorErrStr(msglog); // Error al acceder al registro
3149                                errorInfo(modulo, msglog);
3150                                return (FALSE);
3151                        }
3152                        if (!tbl.ISEOF()) { // Si existe registro
3153                                if (!tbl.Get("identificador", tbidsoftware[i])) {
3154                                        tbl.GetErrorErrStr(msglog); // Error al acceder al registro
3155                                        errorInfo(modulo, msglog);
3156                                        return (FALSE);
3157                                }
3158                        }
3159                } else {
3160                        if (!tbl.Get("idsoftware", tbidsoftware[i])) { // Toma dato
3161                                tbl.GetErrorErrStr(msglog); // Error al acceder al registro
3162                                errorInfo(modulo, msglog);
3163                                return (FALSE);
3164                        }
3165                }
3166        }
3167
3168        // Ordena tabla de identificadores para cosultar si existe un pefil con esas especificaciones
3169
3170        for (i = 0; i < lon - 1; i++) {
3171                for (j = i + 1; j < lon; j++) {
3172                        if (tbidsoftware[i] > tbidsoftware[j]) {
3173                                aux = tbidsoftware[i];
3174                                tbidsoftware[i] = tbidsoftware[j];
3175                                tbidsoftware[j] = aux;
3176                        }
3177                }
3178        }
3179        /* Crea cadena de identificadores de componentes software separados por coma */
3180        sprintf(strInt, "%d", tbidsoftware[lon - 1]); // Pasa a cadena el último identificador que es de mayor longitud
3181        aux = strlen(strInt); // Calcula longitud de cadena para reservar espacio a todos los perfiles
3182        idsoftwares = reservaMemoria((sizeof(aux)+1) * lon + lon);
3183        if (idsoftwares == NULL) {
3184                errorLog(modulo, 3, FALSE);
3185                return (FALSE);
3186        }
3187        aux = sprintf(idsoftwares, "%d", tbidsoftware[0]);
3188        for (i = 1; i < lon; i++)
3189                aux += sprintf(idsoftwares + aux, ",%d", tbidsoftware[i]);
3190
3191        // Comprueba existencia de perfil software y actualización de éste para el ordenador
3192        if (!cuestionPerfilSoftware(db, tbl, idc, ido, idperfilsoft, idsoftwares,
3193                        npc, par, tbidsoftware, lon)) {
3194                errorLog(modulo, 83, FALSE);
3195                errorInfo(modulo, msglog);
3196                retval=FALSE;
3197        }
3198        else {
3199                retval=TRUE;
3200        }
3201        liberaMemoria(wsft);
3202        liberaMemoria(idsoftwares);
3203        return (retval);
3204}
3205// ________________________________________________________________________________________________________
3206// Función: CuestionPerfilSoftware
3207//
3208//      Parámetros:
3209//              - db: Objeto base de datos (ya operativo)
3210//              - tbl: Objeto tabla
3211//              - idcentro: Identificador del centro en la tabla
3212//              - ido: Identificador del ordenador del cliente en la tabla
3213//              - idsoftwares: Cadena con los identificadores de componentes software separados por comas
3214//              - npc: Nombre del ordenador del cliente
3215//              - particion: Número de la partición
3216//              - tbidsoftware: Array con los identificadores de componentes software
3217//              - lon: Número de componentes
3218//      Devuelve:
3219//              TRUE: Si el proceso es correcto
3220//              FALSE: En caso de ocurrir algún error
3221//________________________________________________________________________________________________________/
3222BOOLEAN cuestionPerfilSoftware(Database db, Table tbl, char* idc, char* ido,
3223                int idperfilsoftware, char *idsoftwares, char *npc, char *par,
3224                int *tbidsoftware, int lon) {
3225        char *sqlstr, msglog[LONSTD];
3226        int i, nwidperfilsoft;
3227        char modulo[] = "cuestionPerfilSoftware()";
3228
3229        sqlstr = reservaMemoria(strlen(idsoftwares)+LONSQL); // Reserva para escribir sentencia SQL
3230        if (sqlstr == NULL) {
3231                errorLog(modulo, 3, FALSE);
3232                return (FALSE);
3233        }
3234        // Busca perfil soft del ordenador que contenga todos los componentes software encontrados
3235        sprintf(sqlstr, "SELECT idperfilsoft FROM"
3236                " (SELECT perfilessoft_softwares.idperfilsoft as idperfilsoft,"
3237                "       group_concat(cast(perfilessoft_softwares.idsoftware AS char( 11) )"
3238                "       ORDER BY perfilessoft_softwares.idsoftware SEPARATOR ',' ) AS idsoftwares"
3239                " FROM  perfilessoft_softwares"
3240                " GROUP BY perfilessoft_softwares.idperfilsoft) AS temp"
3241                " WHERE idsoftwares LIKE '%s'", idsoftwares);
3242        // Ejecuta consulta
3243        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3244                errorLog(modulo, 21, FALSE);
3245                db.GetErrorErrStr(msglog);
3246                errorInfo(modulo, msglog);
3247                liberaMemoria(sqlstr);
3248                return (false);
3249        }
3250        if (tbl.ISEOF()) { // No existe un perfil software con esos componentes de componentes software, lo crea
3251                sprintf(sqlstr, "INSERT perfilessoft  (descripcion,idcentro,grupoid)"
3252                                " VALUES('Perfil Software (%s, Part:%s) ',%s,0)", npc, par, idc);
3253                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3254                        db.GetErrorErrStr(msglog);
3255                        errorInfo(modulo, msglog);
3256                        return (false);
3257                }
3258                // Recupera el identificador del nuevo perfil software
3259                sprintf(sqlstr, "SELECT LAST_INSERT_ID() as identificador");
3260                if (!db.Execute(sqlstr, tbl)) { // Error al leer
3261                        tbl.GetErrorErrStr(msglog);
3262                        errorInfo(modulo, msglog);
3263                        liberaMemoria(sqlstr);
3264                        return (false);
3265                }
3266                if (!tbl.ISEOF()) { // Si existe registro
3267                        if (!tbl.Get("identificador", nwidperfilsoft)) {
3268                                tbl.GetErrorErrStr(msglog);
3269                                errorInfo(modulo, msglog);
3270                                liberaMemoria(sqlstr);
3271                                return (false);
3272                        }
3273                }
3274                // Crea la relación entre perfiles y componenetes software
3275                for (i = 0; i < lon; i++) {
3276                        sprintf(sqlstr, "INSERT perfilessoft_softwares (idperfilsoft,idsoftware)"
3277                                                " VALUES(%d,%d)", nwidperfilsoft, tbidsoftware[i]);
3278                        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3279                                db.GetErrorErrStr(msglog);
3280                                errorInfo(modulo, msglog);
3281                                liberaMemoria(sqlstr);
3282                                return (false);
3283                        }
3284                }
3285        } else { // Existe un perfil con todos esos componentes
3286                if (!tbl.Get("idperfilsoft", nwidperfilsoft)) {
3287                        tbl.GetErrorErrStr(msglog);
3288                        errorInfo(modulo, msglog);
3289                        liberaMemoria(sqlstr);
3290                        return (false);
3291                }
3292        }
3293
3294        if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
3295                // Actualiza el identificador del perfil software del ordenador
3296                sprintf(sqlstr, "UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
3297                                " WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
3298                if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3299                        db.GetErrorErrStr(msglog);
3300                        errorInfo(modulo, msglog);
3301                        liberaMemoria(sqlstr);
3302                        return (false);
3303                }
3304        }
3305
3306        /* DEPURACIÓN DE PERFILES SOFTWARE */
3307
3308         /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
3309        sprintf(sqlstr, "DELETE FROM perfilessoft_softwares WHERE idperfilsoft IN "\
3310                " (SELECT idperfilsoft FROM perfilessoft WHERE idperfilsoft NOT IN"\
3311                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones) AND idperfilsoft NOT IN"\
3312                " (SELECT DISTINCT idperfilsoft from imagenes))");
3313        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3314                db.GetErrorErrStr(msglog);
3315                errorInfo(modulo, msglog);
3316                liberaMemoria(sqlstr);
3317                return (false);
3318        }
3319        /* Eliminar Perfiles software que quedan húerfanos */
3320        sprintf(sqlstr, "DELETE FROM perfilessoft WHERE idperfilsoft NOT IN"
3321                " (SELECT DISTINCT idperfilsoft from ordenadores_particiones)"\
3322                " AND  idperfilsoft NOT IN"\
3323                " (SELECT DISTINCT idperfilsoft from imagenes)");
3324        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3325                db.GetErrorErrStr(msglog);
3326                errorInfo(modulo, msglog);
3327                liberaMemoria(sqlstr);
3328                return (false);
3329        }
3330        /* Eliminar Relación de softwares con Perfiles software que quedan húerfanos */
3331        sprintf(sqlstr, "DELETE FROM perfilessoft_softwares WHERE idperfilsoft NOT IN"
3332                        " (SELECT idperfilsoft from perfilessoft)");
3333        if (!db.Execute(sqlstr, tbl)) { // Error al insertar
3334                db.GetErrorErrStr(msglog);
3335                errorInfo(modulo, msglog);
3336                liberaMemoria(sqlstr);
3337                return (false);
3338        }
3339        liberaMemoria(sqlstr);
3340        return (TRUE);
3341}
3342// ________________________________________________________________________________________________________
3343// Función: enviaArchivo
3344//
3345//      Descripción:
3346//              Envia un archivo por la red, por bloques
3347//      Parámetros:
3348//              - socket_c: Socket del cliente que envió el mensaje
3349//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
3350//      Devuelve:
3351//              TRUE: Si el proceso es correcto
3352//              FALSE: En caso de ocurrir algún error
3353// ________________________________________________________________________________________________________
3354BOOLEAN enviaArchivo(SOCKET *socket_c, TRAMA *ptrTrama) {
3355        char *nfl;
3356        char modulo[] = "enviaArchivo()";
3357
3358        // Toma parámetros
3359        nfl = copiaParametro("nfl",ptrTrama); // Toma nombre completo del archivo
3360        if (!sendArchivo(socket_c, nfl)) {
3361                liberaMemoria(nfl);
3362                errorLog(modulo, 57, FALSE);
3363                return (FALSE);
3364        }
3365        liberaMemoria(nfl);
3366        return (TRUE);
3367}
3368// ________________________________________________________________________________________________________
3369// Función: enviaArchivo
3370//
3371//      Descripción:
3372//              Envia un archivo por la red, por bloques
3373//      Parámetros:
3374//              - socket_c: Socket del cliente que envió el mensaje
3375//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
3376//      Devuelve:
3377//              TRUE: Si el proceso es correcto
3378//              FALSE: En caso de ocurrir algún error
3379// ________________________________________________________________________________________________________
3380BOOLEAN recibeArchivo(SOCKET *socket_c, TRAMA *ptrTrama) {
3381        char *nfl;
3382        char modulo[] = "recibeArchivo()";
3383
3384        // Toma parámetros
3385        nfl = copiaParametro("nfl",ptrTrama); // Toma nombre completo del archivo
3386        ptrTrama->tipo = MSG_NOTIFICACION;
3387        enviaFlag(socket_c, ptrTrama);
3388        if (!recArchivo(socket_c, nfl)) {
3389                liberaMemoria(nfl);
3390                errorLog(modulo, 58, FALSE);
3391                return (FALSE);
3392        }
3393        liberaMemoria(nfl);
3394        return (TRUE);
3395}
3396// ________________________________________________________________________________________________________
3397// Función: envioProgramacion
3398//
3399//      Descripción:
3400//              Envia un comando de actualización a todos los ordenadores que han sido programados con
3401//              alguna acción para que entren en el bucle de comandos pendientes y las ejecuten
3402//      Parámetros:
3403//              - socket_c: Socket del cliente que envió el mensaje
3404//              - ptrTrama: Trama recibida por el servidor con el contenido y los parámetros
3405//      Devuelve:
3406//              TRUE: Si el proceso es correcto
3407//              FALSE: En caso de ocurrir algún error
3408// ________________________________________________________________________________________________________
3409BOOLEAN envioProgramacion(SOCKET *socket_c, TRAMA *ptrTrama)
3410{
3411        char sqlstr[LONSQL], msglog[LONSTD];
3412        char *idp,*mar,iph[LONIP],mac[LONMAC];
3413        Database db;
3414        Table tbl;
3415        int idx,idcomando;
3416        char modulo[] = "envioProgramacion()";
3417
3418        if (!db.Open(usuario, pasguor, datasource, catalog)) { // Error de conexion
3419                errorLog(modulo, 20, FALSE);
3420                db.GetErrorErrStr(msglog);
3421                errorInfo(modulo, msglog);
3422                return (FALSE);
3423        }
3424
3425        idp = copiaParametro("idp",ptrTrama); // Toma identificador de la programación de la tabla acciones
3426
3427        sprintf(sqlstr, "SELECT ordenadores.ip,ordenadores.mac,acciones.idcomando FROM acciones "\
3428                        " INNER JOIN ordenadores ON ordenadores.ip=acciones.ip"\
3429                        " WHERE acciones.idprogramacion=%s",idp);
3430       
3431        liberaMemoria(idp);
3432                       
3433        if (!db.Execute(sqlstr, tbl)) { // Error al leer
3434                errorLog(modulo, 21, FALSE);
3435                db.GetErrorErrStr(msglog);
3436                errorInfo(modulo, msglog);
3437                return (FALSE);
3438        }
3439        db.Close();
3440        if(tbl.ISEOF())
3441                return (TRUE); // No existen registros
3442
3443        /* Prepara la trama de actualizacion */
3444
3445        initParametros(ptrTrama,0);
3446        ptrTrama->tipo=MSG_COMANDO;
3447        sprintf(ptrTrama->parametros, "nfn=Actualizar\r");
3448
3449        while (!tbl.ISEOF()) { // Recorre particiones
3450                if (!tbl.Get("ip", iph)) {
3451                        tbl.GetErrorErrStr(msglog);
3452                        errorInfo(modulo, msglog);
3453                        return (FALSE);
3454                }
3455                if (!tbl.Get("idcomando", idcomando)) {
3456                        tbl.GetErrorErrStr(msglog);
3457                        errorInfo(modulo, msglog);
3458                        return (FALSE);
3459                }
3460                if(idcomando==1){ // Arrancar
3461                        if (!tbl.Get("mac", mac)) {
3462                                tbl.GetErrorErrStr(msglog);
3463                                errorInfo(modulo, msglog);
3464                                return (FALSE);
3465                        }
3466
3467                        //mar = copiaParametro("mar",ptrTrama); // Toma modo de arranque si el comando es Arrancar
3468
3469                        // Se manda por broadcast y por unicast
3470                        if (!Levanta(iph,mac,"1")) {
3471                                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
3472                                errorInfo(modulo, msglog);
3473                                liberaMemoria(mar);
3474                                return (FALSE);
3475                        }
3476
3477                        if (!Levanta(iph,mac,"2")) {
3478                                sprintf(msglog, "%s:%s", tbErrores[32], modulo);
3479                                errorInfo(modulo, msglog);
3480                                liberaMemoria(mar);
3481                                return (FALSE);
3482                        }
3483
3484                        liberaMemoria(mar);
3485                }
3486                if (clienteDisponible(iph, &idx)) { // Si el cliente puede recibir comandos
3487                        strcpy(tbsockets[idx].estado, CLIENTE_OCUPADO); // Actualiza el estado del cliente
3488                        if (!mandaTrama(&tbsockets[idx].sock, ptrTrama)) {
3489                                errorLog(modulo, 26, FALSE);
3490                                return (FALSE);
3491                        }
3492                        //close(tbsockets[idx].sock); // Cierra el socket del cliente hasta nueva disponibilidad
3493                }
3494                tbl.MoveNext();
3495        }
3496        return (TRUE); // No existen registros
3497}
3498// ********************************************************************************************************
3499// PROGRAMA PRINCIPAL (SERVICIO)
3500// ********************************************************************************************************
3501int main(int argc, char *argv[]) {
3502        int i;
3503        SOCKET socket_s; // Socket donde escucha el servidor
3504        SOCKET socket_c; // Socket de los clientes que se conectan
3505        socklen_t iAddrSize;
3506        struct sockaddr_in local, cliente;
3507        char modulo[] = "main()";
3508
3509        /*--------------------------------------------------------------------------------------------------------
3510         Validación de parámetros de ejecución y lectura del fichero de configuración del servicio
3511         ---------------------------------------------------------------------------------------------------------*/
3512        if (!validacionParametros(argc, argv, 1)) // Valida parámetros de ejecución
3513                exit(EXIT_FAILURE);
3514
3515        if (!tomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuracion
3516                exit(EXIT_FAILURE);
3517        }
3518        /*--------------------------------------------------------------------------------------------------------
3519         Carga del catálogo de funciones que procesan las tramas (referencia directa por puntero a función)
3520         ---------------------------------------------------------------------------------------------------------*/
3521        int cf = 0;
3522
3523        strcpy(tbfuncionesServer[cf].nf, "Sondeo");
3524        tbfuncionesServer[cf++].fptr = &Sondeo;
3525        strcpy(tbfuncionesServer[cf].nf, "respuestaSondeo");
3526        tbfuncionesServer[cf++].fptr = &respuestaSondeo;
3527
3528        strcpy(tbfuncionesServer[cf].nf, "ConsolaRemota");
3529        tbfuncionesServer[cf++].fptr = &ConsolaRemota;
3530
3531        strcpy(tbfuncionesServer[cf].nf, "EcoConsola");
3532        tbfuncionesServer[cf++].fptr = &EcoConsola;
3533
3534        strcpy(tbfuncionesServer[cf].nf, "Actualizar");
3535        tbfuncionesServer[cf++].fptr = &Actualizar;
3536
3537        strcpy(tbfuncionesServer[cf].nf, "Purgar");
3538        tbfuncionesServer[cf++].fptr = &Purgar;
3539
3540        strcpy(tbfuncionesServer[cf].nf, "InclusionCliente");
3541        tbfuncionesServer[cf++].fptr = &InclusionCliente;
3542
3543        strcpy(tbfuncionesServer[cf].nf, "InclusionClienteWinLnx");
3544        tbfuncionesServer[cf++].fptr = &InclusionClienteWinLnx;
3545
3546        strcpy(tbfuncionesServer[cf].nf, "AutoexecCliente");
3547        tbfuncionesServer[cf++].fptr = &AutoexecCliente;
3548
3549        strcpy(tbfuncionesServer[cf].nf, "ComandosPendientes");
3550        tbfuncionesServer[cf++].fptr = &ComandosPendientes;
3551
3552        strcpy(tbfuncionesServer[cf].nf, "DisponibilidadComandos");
3553        tbfuncionesServer[cf++].fptr = &DisponibilidadComandos;
3554
3555        strcpy(tbfuncionesServer[cf].nf, "Arrancar");
3556        tbfuncionesServer[cf++].fptr = &Arrancar;
3557        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_Arrancar");
3558        tbfuncionesServer[cf++].fptr = &RESPUESTA_Arrancar;
3559
3560        strcpy(tbfuncionesServer[cf].nf, "Apagar");
3561        tbfuncionesServer[cf++].fptr = &Apagar;
3562        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_Apagar");
3563        tbfuncionesServer[cf++].fptr = &RESPUESTA_Apagar;
3564
3565        strcpy(tbfuncionesServer[cf].nf, "Reiniciar");
3566        tbfuncionesServer[cf++].fptr = &Reiniciar;
3567        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_Reiniciar");
3568        tbfuncionesServer[cf++].fptr = &RESPUESTA_Reiniciar;
3569
3570        strcpy(tbfuncionesServer[cf].nf, "IniciarSesion");
3571        tbfuncionesServer[cf++].fptr = &IniciarSesion;
3572        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_IniciarSesion");
3573        tbfuncionesServer[cf++].fptr = &RESPUESTA_IniciarSesion;
3574
3575        strcpy(tbfuncionesServer[cf].nf, "CrearImagen");
3576        tbfuncionesServer[cf++].fptr = &CrearImagen;
3577        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_CrearImagen");
3578        tbfuncionesServer[cf++].fptr = &RESPUESTA_CrearImagen;
3579
3580        strcpy(tbfuncionesServer[cf].nf, "CrearImagenBasica");
3581        tbfuncionesServer[cf++].fptr = &CrearImagenBasica;
3582        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_CrearImagenBasica");
3583        tbfuncionesServer[cf++].fptr = &RESPUESTA_CrearImagenBasica;
3584
3585        strcpy(tbfuncionesServer[cf].nf, "CrearSoftIncremental");
3586        tbfuncionesServer[cf++].fptr = &CrearSoftIncremental;
3587        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_CrearSoftIncremental");
3588        tbfuncionesServer[cf++].fptr = &RESPUESTA_CrearSoftIncremental;
3589
3590        strcpy(tbfuncionesServer[cf].nf, "RestaurarImagen");
3591        tbfuncionesServer[cf++].fptr = &RestaurarImagen;
3592        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_RestaurarImagen");
3593        tbfuncionesServer[cf++].fptr = &RESPUESTA_RestaurarImagen;
3594
3595        strcpy(tbfuncionesServer[cf].nf, "RestaurarImagenBasica");
3596        tbfuncionesServer[cf++].fptr = &RestaurarImagenBasica;
3597        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_RestaurarImagenBasica");
3598        tbfuncionesServer[cf++].fptr = &RESPUESTA_RestaurarImagenBasica;
3599
3600        strcpy(tbfuncionesServer[cf].nf, "RestaurarSoftIncremental");
3601        tbfuncionesServer[cf++].fptr = &RestaurarSoftIncremental;
3602        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_RestaurarSoftIncremental");
3603        tbfuncionesServer[cf++].fptr = &RESPUESTA_RestaurarSoftIncremental;
3604
3605        strcpy(tbfuncionesServer[cf].nf, "Configurar");
3606        tbfuncionesServer[cf++].fptr = &Configurar;
3607        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_Configurar");
3608        tbfuncionesServer[cf++].fptr = &RESPUESTA_Configurar;
3609
3610        strcpy(tbfuncionesServer[cf].nf, "EjecutarScript");
3611        tbfuncionesServer[cf++].fptr = &EjecutarScript;
3612        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_EjecutarScript");
3613        tbfuncionesServer[cf++].fptr = &RESPUESTA_EjecutarScript;
3614
3615        strcpy(tbfuncionesServer[cf].nf, "InventarioHardware");
3616        tbfuncionesServer[cf++].fptr = &InventarioHardware;
3617        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_InventarioHardware");
3618        tbfuncionesServer[cf++].fptr = &RESPUESTA_InventarioHardware;
3619
3620        strcpy(tbfuncionesServer[cf].nf, "InventarioSoftware");
3621        tbfuncionesServer[cf++].fptr = &InventarioSoftware;
3622        strcpy(tbfuncionesServer[cf].nf, "RESPUESTA_InventarioSoftware");
3623        tbfuncionesServer[cf++].fptr = &RESPUESTA_InventarioSoftware;
3624
3625        strcpy(tbfuncionesServer[cf].nf, "enviaArchivo");
3626        tbfuncionesServer[cf++].fptr = &enviaArchivo;
3627
3628        strcpy(tbfuncionesServer[cf].nf, "recibeArchivo");
3629        tbfuncionesServer[cf++].fptr = &recibeArchivo;
3630
3631        strcpy(tbfuncionesServer[cf].nf, "envioProgramacion");
3632        tbfuncionesServer[cf++].fptr = &envioProgramacion;
3633
3634        /*--------------------------------------------------------------------------------------------------------
3635         // Inicializa array de información de los clientes
3636         ---------------------------------------------------------------------------------------------------------*/
3637        for (i = 0; i < MAXIMOS_CLIENTES; i++) {
3638                tbsockets[i].ip[0] = '\0';
3639                tbsockets[i].sock = INVALID_SOCKET;
3640        }
3641        /*--------------------------------------------------------------------------------------------------------
3642         Creación y configuración del socket del servicio
3643         ---------------------------------------------------------------------------------------------------------*/
3644        socket_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Crea socket del servicio
3645        if (socket_s == SOCKET_ERROR) { // Error al crear el socket del servicio
3646                errorLog(modulo, 13, TRUE);
3647                exit(EXIT_FAILURE);
3648        }
3649
3650        local.sin_addr.s_addr = htonl(INADDR_ANY); // Configura el socket del servicio
3651        local.sin_family = AF_INET;
3652        local.sin_port = htons(atoi(puerto));
3653
3654        if (bind(socket_s, (struct sockaddr *) &local, sizeof(local))
3655                        == SOCKET_ERROR) { // Enlaza socket
3656                errorLog(modulo, 14, TRUE);
3657                exit(EXIT_FAILURE);
3658        }
3659
3660        listen(socket_s, 250); // Pone a escuchar al socket
3661        iAddrSize = sizeof(cliente);
3662        /*--------------------------------------------------------------------------------------------------------
3663         Bucle para acceptar conexiones
3664         ---------------------------------------------------------------------------------------------------------*/
3665        infoLog(1); // Inicio de sesión
3666        while (TRUE) {
3667                socket_c = accept(socket_s, (struct sockaddr *) &cliente, &iAddrSize);
3668                if (socket_c == INVALID_SOCKET) {
3669                        errorLog(modulo, 15, TRUE);
3670                        exit(EXIT_FAILURE);
3671                }
3672                swcSocket = FALSE; // Por defecto se cerrara el socket de cliente después del anális de la trama
3673                if (!gestionaTrama(&socket_c)) {
3674                        errorLog(modulo, 39, TRUE);
3675                        //close(socket_c);/tmp/
3676                        //break;
3677                }
3678                if (!swcSocket) // Sólo se cierra cuando el cliente NO espera comandos ineractivos
3679                        close(socket_c);
3680        }
3681        /*--------------------------------------------------------------------------------------------------------
3682         Fin del servicio
3683         ---------------------------------------------------------------------------------------------------------*/
3684        close(socket_s);
3685        exit(EXIT_SUCCESS);
3686}
Note: See TracBrowser for help on using the repository browser.