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

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 cad1e1b was 6e235cd, checked in by alonso <alonso@…>, 12 years ago

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

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