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

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 b9a6500 was 3ec149c, checked in by alonso <alonso@…>, 15 years ago

git-svn-id: https://opengnsys.es/svn/trunk@1314 a21b9725-9963-47de-94b9-378ad31fedc9

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