source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ 9583e59

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 9583e59 was 048494e, checked in by ramon <ramongomez@…>, 13 years ago

#559: Corregir errata al liberar memoria antes de tomar los parámetros de arranque de ogAdmServer.

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

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