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

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

#501: Integrar ticket en rama de desarrollo.

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

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