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

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 d475799 was 5f9eca0, checked in by ramon <ramongomez@…>, 12 years ago

#601: Si no se obtiene código de partición, asignar a 0 (EMPTY).

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

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