/* OpenIDA - Outil d'analyse de fichiers binaires * client.c - connexion à un serveur Chrysalide * * Copyright (C) 2014 Cyrille Bagard * * This file is part of OpenIDA. * * OpenIDA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * OpenIDA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "client.h" #include #include #include #include #include #include #include "protocol.h" /* Description de client à l'écoute (instance) */ struct _GDbClient { GObject parent; /* A laisser en premier */ int fd; struct sockaddr_in addr; /* Adresse d'écoute */ GThread *update; /* Procédure de traitement */ }; /* Description de client à l'écoute (classe) */ struct _GDbClientClass { GObjectClass parent; /* A laisser en premier */ }; /* Initialise la classe des descriptions de fichier binaire. */ static void g_db_client_class_init(GDbClientClass *); /* Initialise une description de fichier binaire. */ static void g_db_client_init(GDbClient *); /* Procède à la libération totale de la mémoire. */ static void g_db_client_finalize(GDbClient *); /* Assure l'accueil des nouvelles mises à jour. */ static void *g_db_client_update(GDbClient *); /* Indique le type défini pour une description de client à l'écoute. */ G_DEFINE_TYPE(GDbClient, g_db_client, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des descriptions de fichier binaire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_db_client_class_init(GDbClientClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->finalize = (GObjectFinalizeFunc)g_db_client_finalize; } /****************************************************************************** * * * Paramètres : client = instance à initialiser. * * * * Description : Initialise une description de fichier binaire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_db_client_init(GDbClient *client) { client->fd = -1; } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_db_client_finalize(GDbClient *binary) { //free(binary->filename); G_OBJECT_CLASS(g_db_client_parent_class)->finalize(G_OBJECT(binary)); } /****************************************************************************** * * * Paramètres : host = hôte à représenter pour le service. * * port = port de connexion pour les clients. * * * * Description : Prépare un client pour une connexion à une BD. * * * * Retour : Structure mise en plae ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GDbClient *g_db_client_new(const char *host, short port) { GDbClient *result; /* Adresse à retourner */ struct hostent *hp; /* Informations sur l'hôte */ result = g_object_new(G_TYPE_DB_CLIENT, NULL); hp = gethostbyname(host); if (hp == NULL) goto gdsn_error; result->addr.sin_family = hp->h_addrtype; memcpy(&result->addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); result->addr.sin_port = htons(port); return result; gdsn_error: g_object_unref(G_OBJECT(result)); return NULL; } /****************************************************************************** * * * Paramètres : client = client pour les accès distants à manipuler. * * * * Description : Assure l'accueil des nouvelles mises à jour. * * * * Retour : NULL. * * * * Remarques : - * * * ******************************************************************************/ static void *g_db_client_update(GDbClient *client) { struct pollfd fds; /* Surveillance des flux */ int ret; /* Bilan d'un appel */ fds.fd = client->fd; fds.events = POLLIN | POLLPRI; while (1) { ret = poll(&fds, 1, -1); if (ret != 1) continue; printf("fds.revents :: %x\n", fds.revents); /* Le canal est fermé, une sortie doit être demandée... */ if (fds.revents & POLLNVAL) break; if (fds.revents & (POLLIN | POLLPRI)) { /* TODO */ pause(); } } g_db_client_stop(client); return NULL; } /****************************************************************************** * * * Paramètres : client = client pour les accès distants à manipuler. * * * * Description : Démarre la connexion à la base de données. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_db_client_start(GDbClient *client) { int ret; /* Bilan d'un appel */ client->fd = socket(AF_INET, SOCK_STREAM, 0); if (client->fd == -1) { perror("socket"); return false; } ret = connect(client->fd, (struct sockaddr *)&client->addr, sizeof(struct sockaddr_in)); if (ret == -1) { perror("connect"); close(client->fd); client->fd = -1; return false; } //client->update = g_thread_new("cdb_listener", (GThreadFunc)g_db_client_update, client); send(client->fd, "A", 1, 0); return true; } /****************************************************************************** * * * Paramètres : client = client pour les accès distants à manipuler. * * * * Description : Arrête la connexion à la base de données. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_db_client_stop(GDbClient *client) { if (client->fd != -1) return; close(client->fd); client->fd = -1; g_thread_join(client->update); }