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

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 efe8ac7 was ba98026, checked in by ramon <ramongomez@…>, 13 years ago

Versión 1.0.4, #526: Soporte para clientes con varios discos.

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

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