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

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 d866d6b was 4329e85, checked in by ramon <ramongomez@…>, 12 years ago

Versión 1.0.5, #565: Integrar código del ticket:565 en rama de desarrollo.

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

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