source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ 7cd5122

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 7cd5122 was b0c9683, checked in by ramon <ramongomez@…>, 10 years ago

#711: Integrar código del ticket:711 y modificar ogAdmServer para guardar porcentaje de uso en la BD.

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

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