source: admin/Sources/Services/ogAdmServer/sources/ogAdmServer.cpp @ 2d39301

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 2d39301 was 82e5b6c, checked in by ramon <ramongomez@…>, 8 years ago

#730 #738: Si se reinicia el servicio ogAdmServer, se reutiliza el pureto en Linux 3.9+; se actualiza la configuración del cliente tras el comando Restaurar Imagen (falta aplicar cambios en imagen básica).

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

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