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

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 ee4beb4 was f55923d, checked in by ramon <ramongomez@…>, 11 years ago

#621: Corregir errata en la función respuestaEstandar del servicio ogAdmServer para obtener correctamente el resultado de una operación.

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

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