source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ 5105e58

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since 5105e58 was 0d1f74f, checked in by ramon <ramongomez@…>, 12 years ago

#601: Integrar código revisión r3855, borrando configuración del cliente antes de volver a crearla.

git-svn-id: https://opengnsys.es/svn/branches/version1.0@3856 a21b9725-9963-47de-94b9-378ad31fedc9

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