Browse Source

first flow of .h, one main() compilng

master
tonton Th 2 years ago
parent
commit
850cf9d8bd
14 changed files with 873 additions and 5 deletions
  1. +1
    -0
      .gitignore
  2. +14
    -5
      README.md
  3. +25
    -0
      broadcast.h
  4. +20
    -0
      clients.h
  5. +47
    -0
      commands.h
  6. +15
    -0
      config.h
  7. +31
    -0
      defines.h
  8. +16
    -0
      drinks.h
  9. +576
    -0
      guinnessd.c
  10. +37
    -0
      guinnessd.h
  11. +27
    -0
      lists.h
  12. +18
    -0
      printlog.h
  13. +20
    -0
      tools.h
  14. +26
    -0
      xmem.h

+ 1
- 0
.gitignore View File

@ -0,0 +1 @@
*.o

+ 14
- 5
README.md View File

@ -1,20 +1,29 @@
# Guinness Server
## Origine :
[Official Website of Guinnessd](http://tnemeth.free.fr/projets/guinness-server.html)
[Official Website](http://tnemeth.free.fr/projets/guinness-server.html)
## Origine :
La version d'origine a un **gros** souci :
le `Makefile` tourne désepérement
en boucle ! J'ai donc décidé, pour occuper mes longues journées de
[en boucle](boucle-de-make.txt) !
J'ai donc décidé, pour occuper mes longues journées de
retraite sanitaire, de sortir la disqueuse et de tenter de trouver
le bug.
le bug. Et ça ne va pas être simple, le Makefile d'origine est
**très** convolué...
## Methodologie :
## Méthodologie :
Pour commencer, je vais utiliser un mélange de [rache](https://la-rache.com/)
et de [poudre verte](https://poudreverte.org/), additionné d'un peu de
jus de citron pour le goût...
Première étape : tenter de compiler le `main()` du serveur. Oké, il demande
un certain nombre de `.h`, que je m'empresse de lui fournir à partir de
l'original. C'est au moment où il me demande le `config.h` que j'allume
la disqueuse, je n'ai qu'un `config.h.in` sous la main.
## Résultat :
« Ah, c'est l'heure d'aller boire une bière, et comme il ne faut jamais
boire le ventre vide, je vais manger une Guinness avant. »

+ 25
- 0
broadcast.h View File

@ -0,0 +1,25 @@
/*
* guinnessd
* architecture clients/serveur guinness : broadcast messages
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNNESS_BROADCAST
#define GUINNNESS_BROADCAST
#include "guinnessd.h"
#define QUITTER 1
#define TOURNEE 2
#define MESSAGE 3
int broadcast (int t, const char *f, const char *m);
int new_message (long cid);
int get_broadcastid ();
void get_broadcastmsg (int *t, char **f, char **m);
int send_broadcast (int socket_service, userinfos *infos);
#endif

+ 20
- 0
clients.h View File

@ -0,0 +1,20 @@
/*
* clients
* architecture clients/serveur guinness
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNESS_CLIENTS
#define GUINNESS_CLIENTS
void add_client (userinfos *infos);
void remove_client (userinfos *infos);
int rename_client (userinfos *infos, const char *new_nick);
char *list_clients ();
char *infos_client (int admin, const char *nick);
#endif

+ 47
- 0
commands.h View File

@ -0,0 +1,47 @@
/*
* commands
* architecture clients/serveur guinness
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef SERVER_COMMANDS
#define SERVER_COMMANDS
/*#define MAXCMDS 14*/
typedef struct cmdslst {
char *nom;
char *aide;
int args;
int adm;
int interv;
int (*fct)();
} cmdslst;
int reply (int socket_service, char *commande, userinfos *infos);
int send_servercmds (int socket_service);
/* Fonctions associées aux commandes */
int f_help (int socket_service, const char *commande, userinfos *infos);
int f_quit (int socket_service, const char *commande, userinfos *infos);
int f_list (int socket_service, const char *commande, userinfos *infos);
int f_bevr (int socket_service, const char *commande, userinfos *infos);
int f_cold (int socket_service, const char *commande, userinfos *infos);
int f_turn (int socket_service, const char *commande, userinfos *infos);
int f_mesg (int socket_service, const char *commande, userinfos *infos);
int f_info (int socket_service, const char *commande, userinfos *infos);
int f_nick (int socket_service, const char *commande, userinfos *infos);
int f_glas (int socket_service, const char *commande, userinfos *infos);
int f_sadm (int socket_service, const char *commande, userinfos *infos);
int f_shut (int socket_service, const char *commande, userinfos *infos);
int f_rldb (int socket_service, const char *commande, userinfos *infos);
int f_addu (int socket_service, const char *commande, userinfos *infos);
int f_delu (int socket_service, const char *commande, userinfos *infos);
int f_save (int socket_service, const char *commande, userinfos *infos);
int f_load (int socket_service, const char *commande, userinfos *infos);
#endif

+ 15
- 0
config.h View File

@ -0,0 +1,15 @@
/*
* from config.h.in :
* architecture clients/serveur guinness : configuration.
* homas Nemeth -- le 15 juin 2001
*
2020-03-28 : handcrafted by tth
*
*/
#define VERSION "0.4.7-tth"
#define OS_TYPE "cp/m 68k"
#define COMPIL_DATE __DATE__
#define DRINKS_DIR "/var/tmp/drinks.d"

+ 31
- 0
defines.h View File

@ -0,0 +1,31 @@
/*
* defines
* Création et manipulation de sockets
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNESS_DEFINES
#define GUINNESS_DEFINES
#include <assert.h>
#define DEFAULT_SERVER_PORT 1664
#define DEFAULT_DRINK "guinness"
#define DEFAULT_LOGOUT "Bye bye..."
#define DEFAULT_PSEUDO "toto"
#define SEP "\n"
#define MAXSTRLEN 4096
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/* Important macros */
#define MY_ALLOC(var, nb, type) \
((var) = malloc((nb)*sizeof(type)), assert((var) != NULL))
#endif

+ 16
- 0
drinks.h View File

@ -0,0 +1,16 @@
/*
* drinks
* architecture clients/serveur guinness : breuvages
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNNESS_BEVRG
#define GUINNNESS_BEVRG
char *drinks_get (const char *nom);
void drinks_list_files (const char *path);
void drinks_display_list ();
#endif

+ 576
- 0
guinnessd.c View File

@ -0,0 +1,576 @@
/*
* guinnessd
* architecture clients/serveur guinness
* Thomas Nemeth -- le 15 juin 2001
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <strings.h>
#include <locale.h>
#include "defines.h"
#include "xmem.h"
#include "tools.h"
#include "printlog.h"
#include "lists.h"
#include "broadcast.h"
#include "drinks.h"
#include "clients.h"
#include "guinnessd.h"
#include "commands.h"
#include "config.h"
/* Config spécifique serveur */
char *adr_ip = NULL;
int port = 0;
int online = TRUE;
char *fichierlog = NULL;
char *fichiercfg = NULL;
char *chemin = NULL;
char *admin_passwd = NULL;
FILE *logfile = NULL;
FILE *outerr = NULL;
Elt *clients_list = NULL;
Elt *drinks_list = NULL;
/* Config spécifique connexion des clients */
char *pseudo = NULL;
char *drink = NULL;
char *logout = NULL;
#ifdef SunOS
char *crypt(const char *key, const char *salt);
#else
extern char *crypt __P ((__const char *__key, __const char *__salt));
#endif
void install_handler ();
/*
* Gestionnaire de signal SIGPIPE, SIGTERM, SIGQUIT et SIGINT
*
*/
void handler_signaux (int sig) {
switch (sig) {
case SIGPIPE:
printlog (LOG_NOTIFY, "Signal SIGPIPE reçu...\n");
install_handler ();
break;
case SIGTERM:
case SIGQUIT:
case SIGINT:
online = FALSE;
printlog (LOG_NOTIFY, "Signal de terminaison reçu...\n");
break;
default:
printlog (LOG_NOTIFY, "Signal reçu...\n");
}
}
/*
* Lecture du fichier de config : récupération des valeurs
*
*/
char *get_string_from_token (char *line) {
char *result = line;
char *tmp;
int keyval = 0;
while ( (keyval != 1) && (result [0] != 0) ) {
if (result [0] == '=') keyval = 1;
if (keyval == 0) result++;
}
tmp = result++;
while (tmp [0] != 0) {
if (tmp [0] == '\n') tmp [0] = 0;
tmp++;
}
return result;
}
/*
* Lecture du fichier de config
*
*/
void load_config () {
FILE *file;
char tmpstr[MAXSTRLEN + 1];
char *value;
/* Ouverture du fichier */
if ( (file = fopen (fichiercfg?fichiercfg:CONFIG_FILE, "r") ) != NULL) {
/* Lecture du fichier */
while (! feof (file) ) {
memset (tmpstr, 0, MAXSTRLEN + 1);
fgets (tmpstr, (int) MAXSTRLEN, file);
value = get_string_from_token (tmpstr);
if ( (strncmp (tmpstr, "port=", 5) == 0) && (port == 0) )
port = atoi (value);
if ( (strncmp (tmpstr, "passwd=", 7) == 0) &&
(admin_passwd == NULL) )
admin_passwd = xstrdup (crypt (value, "Gs") + 2);
if ( (strncmp (tmpstr, "rep=", 4) == 0) && (chemin == NULL) )
chemin = xstrdup (value);
if ( (strncmp (tmpstr, "pseudo=", 7) == 0) && (pseudo == NULL) )
pseudo = xstrdup (value);
if ( (strncmp (tmpstr, "drink=", 6) == 0) && (drink == NULL) )
drink = xstrdup (value);
if ( (strncmp (tmpstr, "logout=", 7) == 0) && (logout == NULL) )
logout = xstrdup (value);
}
fclose (file);
#ifdef DEBUG
} else {
fprintf (stderr, "Pas de fichier de config (%s).\n", CONFIG_FILE);
#endif
}
}
/*
* Aide
*
*/
void Usage (int help) {
printf ("guinnessd by Thomas Nemeth - v %s (compilation %s : %s)\n",
VERSION, OS_TYPE, COMPIL_DATE);
if (help)
printf ("Usage : guinnessd [-h] [-v] [-b] [-p port] "
"[-s passwd] [-d chemin] [-l fichier] [-f fichier]\n"
" -h : aide sur les paramètres\n"
" -v : affiche la version\n"
" -b : détache le serveur du terminal\n"
" -a adresse : spécifie l'adresse du serveur\n"
" -p port : spécifie le numéro du port\n"
" -s passwd : spécifie le mot de passe d'aministration\n"
" -d chemin : indique le chemin où se"
" trouvent les ascii-arts\n"
" -l fichier : fichier de log\n"
" -f fichier : fichier de configuration\n\n");
exit (1);
}
/*
* Traitement des arguments
*
*/
int traite_argv (int argc, char *argv[]) {
int option;
int detach = FALSE;
/* Vérification des paramètres */
while ((option = getopt (argc, argv, "hvba:p:s:d:l:f:")) != -1) {
switch (option) {
case 'h' :
Usage (TRUE);
break;
case 'v' :
Usage (FALSE);
break;
case 'b' :
detach = TRUE;
break;
case 'a' :
adr_ip = optarg;
break;
case 'p' :
port = atoi (optarg);
break;
case 's' :
admin_passwd = xstrdup (crypt (optarg, "Gs") + 2);
break;
case 'd' :
if (! chemin) {
if (optarg[0] == '/') {
chemin = xstrdup (optarg);
} else {
char *Pwd;
Pwd = xmalloc ((MAXSTRLEN + 1) * sizeof (char));
getcwd (Pwd, MAXSTRLEN);
chemin = xmalloc ( (strlen (Pwd) + strlen (optarg) + 2)
* sizeof (char) );
snprintf (chemin, MAXSTRLEN, "%s/%s",
Pwd, optarg);
}
}
break;
case 'l' :
if (! fichierlog) {
fichierlog = xstrdup (optarg);
}
break;
case 'f' :
if (! fichiercfg) {
fichiercfg = xstrdup (optarg);
}
break;
default:
Usage (TRUE);
break;
}
}
if (optind < argc) {
if (argc - optind == 1)
fprintf (stderr, "%s: option inconnue --", argv[0]);
else
fprintf (stderr, "%s: options inconnues --", argv[0]);
for ( ; optind < argc ; optind++)
fprintf (stderr, " %s", argv[optind]);
fprintf (stderr, "\n");
Usage (TRUE);
}
return detach;
}
/*
* Fonction initiant la connexion.
*
*/
int initiate (int socket_service, userinfos *infos) {
int cont = TRUE;
char userdatas[MAXSTRLEN];
char *datas, *token, *saveptr;
char delim[] = "\n\r";
char *nom_distant = NULL;
char *ip_distant = NULL;
int port_distant = 0;
int port_local = 0;
time_t now;
struct tm *today;
memset (userdatas, 0, MAXSTRLEN);
/* Récupération des infos sur le connecté */
get_sock_infos (socket_service,
&nom_distant, &ip_distant,
&port_local, &port_distant);
if (ip_distant) {
snprintf (infos->ip, MAXSTRLEN, "%s", ip_distant);
free (ip_distant);
} else sprintf (infos->ip, "0.0.0.0");
if (nom_distant) {
snprintf (infos->host, MAXSTRLEN, "%s", nom_distant);
free (nom_distant);
} else sprintf (infos->host, "none");
infos->port = port_distant;
printlog (LOG_NOTIFY, "Connexion entrante : %s %s\n",
infos->ip, infos->host ? infos->host : "");
printlog (LOG_NOTIFY, "Ports (loc/dist) : %d / %d\n",
port_local, infos->port);
/* PROTOCOLE DE CONNEXION */
/* 1. envoi des commandes du serveur */
if ( (cont = send_servercmds (socket_service)) == FALSE)
return cont;
/* 2. attente des données du connecté */
if ( (cont = read_infos (socket_service, userdatas)) == FALSE)
return cont;
/* FIN DU PROTOCOLE : Véricifations / ajout dans la liste / affichage */
datas = xstrdup (userdatas);
/* Nom d'utilisateur */
token = strtok_r (datas, delim, &saveptr);
snprintf (infos->nom, MAXSTRLEN, "%s", token ? token : pseudo);
/* Boisson préférée */
token = strtok_r (NULL, delim, &saveptr);
snprintf (infos->prefb, MAXSTRLEN, "%s", token ? token : drink);
/* Message d'au-revoir */
token = strtok_r (NULL, delim, &saveptr);
snprintf (infos->logout, MAXSTRLEN, "%s", token ? token : logout);
/* Date de connexion */
time (&now);
today = localtime (&now);
strftime (infos->cxdate, MAXSTRLEN, "%a %d %b %Y %T", today);
printlog (LOG_NOTIFY, "Utilisateur : [%s]\n", infos->nom);
printlog (LOG_NOTIFY, "Boisson préférée : [%s]\n", infos->prefb);
printlog (LOG_NOTIFY, "Message de logout : [%s]\n", infos->logout);
printlog (LOG_NOTIFY, "Date de connexion : [%s]\n", infos->cxdate);
pthread_mutex_lock (&mutex_clients);
if (exist_elt (clients_list, infos->nom)) {
char nick_ok[MAXSTRLEN];
snprintf (nick_ok, MAXSTRLEN, "@%s", infos->nom);
snprintf (infos->nom, MAXSTRLEN, "%s", nick_ok);
send_infos (socket_service, "@Pseudo déjà utilisé !\n");
printlog (LOG_NOTIFY, "Pseudo déjà utilisé => %s\n", infos->nom);
pthread_mutex_unlock (&mutex_clients);
return FALSE;
}
send_infos (socket_service, "Bienvenue sur le serveur de Guinness.\n");
add_client (infos);
pthread_mutex_unlock (&mutex_clients);
if (! exist_elt (drinks_list, infos->prefb))
send_infos (socket_service,
"Votre boisson préférée n'est pas disponible sur ce"
" serveur !\nVous aurez des Guinness à la place.\n");
/* Passage en mode non bloquant */
fcntl (socket_service, F_SETFL, O_NONBLOCK);
return cont;
}
/*
* Fonction de traitement de la connexion avec les clients
*
*/
void thread_service (int *sock_serv) {
pthread_t tid = pthread_self ();
long old_id = get_broadcastid ();
int socket_service = (int) *sock_serv;
int cont = TRUE;
int nb;
userinfos infos;
char commande[MAXSTRLEN + 1];
pthread_detach (tid);
memset (infos.nom, 0, MAXSTRLEN + 1);
memset (infos.prefb, 0, MAXSTRLEN + 1);
memset (infos.logout, 0, MAXSTRLEN + 1);
infos.admin = FALSE;
infos.cold = FALSE;
cont = initiate (socket_service, &infos);
if (cont) {
snprintf (commande, MAXSTRLEN,
"%s a rejoint le serveur de Guinness.\n", infos.nom);
broadcast (MESSAGE, NULL, commande);
}
#ifdef DEBUG
printlog (LOG_NOTIFY, "Prêt à recevoir des commandes.\n");
#endif
while (cont == TRUE) {
memset (commande, 0, MAXSTRLEN + 1);
/* Lecture des caractères reçus */
do {
sleep (1);
nb = read (socket_service, commande, MAXSTRLEN);
if ( (nb == -1) || (nb == 0) ) {
if ( (errno == EAGAIN) && (nb == -1) ) continue;
if ( (errno == EPIPE) || (nb == 0) ) {
cont = FALSE;
} else {
printlog (LOG_ERROR, "Erreur de connexion réception !\n");
}
}
} while ( (cont != FALSE) &&
(nb < 0) &&
(new_message (old_id) != TRUE) );
#ifdef DEBUG
printlog (LOG_NOTIFY, "Commande reçue.\n");
#endif
if (cont == TRUE) {
/* Traitement de la commande */
if (nb > 0)
cont = reply (socket_service, commande, &infos);
/* Broadcast */
if (new_message (old_id) == TRUE) {
old_id = get_broadcastid ();
cont = send_broadcast (socket_service, &infos);
#ifdef DEBUG
printlog (LOG_ERROR, "Émission broadcast pour %s (id = %ld)\n",
infos.nom, old_id);
#endif
}
}
}
printlog (LOG_NOTIFY, "Bye bye %s...\n", infos.nom);
if (infos.nom[0] != '@') {
pthread_mutex_lock (&mutex_clients);
remove_client (&infos);
pthread_mutex_unlock (&mutex_clients);
broadcast (QUITTER, infos.nom, infos.logout);
}
close (socket_service);
}
/*
* Installation du gestionnaire de signal SIGPIPE et autres...
*
*/
void install_handler () {
signal (SIGPIPE, handler_signaux);
signal (SIGTERM, handler_signaux);
signal (SIGQUIT, handler_signaux);
signal (SIGINT, handler_signaux);
}
/*
* Initialisation générale
*
*/
void guinnessd_init (int argc, char *argv[]) {
pthread_mutexattr_t mutex_attr;
setlocale (LC_ALL, "");
install_handler ();
/* Valeurs par défaut */
logfile = stdout;
outerr = stderr;
/* Traitement des paramètres */
if (traite_argv (argc, argv) == TRUE) {
switch (fork()) {
case -1: /* erreur */
perror ("fork()");
exit (-1);
case 0: /* le fils */
setsid ();
break;
default: /* le père */
exit (0);
}
}
/* Lecture du fichier de configuration */
load_config ();
/* Initialisation des sémaphores */
pthread_mutexattr_init (&mutex_attr);
pthread_mutex_init (&mutex_broadcast, &mutex_attr);
pthread_mutex_init (&mutex_clients, &mutex_attr);
/* Affectation des paramètres */
if (IS_NOT_GOOD (pseudo)) SET_STRING (pseudo, DEFAULT_PSEUDO);
if (IS_NOT_GOOD (drink)) SET_STRING (drink, DEFAULT_DRINK);
if (IS_NOT_GOOD (logout)) SET_STRING (logout, DEFAULT_LOGOUT);
if (port == 0) port = DEFAULT_SERVER_PORT;
if (fichierlog) {
if ((logfile = fopen (fichierlog, "a"))) {
outerr = logfile;
} else {
fprintf (stderr, "Impossible d'ouvrir le fichier %s : %s\n",
fichierlog, strerror(errno));
}
}
/* Option pour le buffer de logs */
setvbuf (logfile, NULL, _IOLBF, 0);
/* Création de la liste de boissons par défaut*/
add_elt (&drinks_list, "guinness");
if (! chemin) chemin = xstrdup (DRINKS_DIR);
drinks_list_files (chemin);
drinks_display_list ();
}
/*
* Fonction principale
*
*/
int main (int argc, char *argv[]) {
int socket_ecoute;
int socket_service;
int lg_adresse = sizeof (struct sockaddr_in);
struct sockaddr_in adresse;
pthread_t pthread_id;
guinnessd_init (argc, argv);
/* Installation de l'écoute du serveur */
if ( (socket_ecoute = install_server (port, adr_ip, NULL)) == -1) {
printlog (LOG_ERROR, "Impossible d'installer le service.\n");
return -1;
}
/* Passage en mode non-bloquant */
fcntl (socket_ecoute, F_SETFL, O_NONBLOCK);
/* Boucle d'attente et d'ouverture de connexions */
printlog (LOG_NOTIFY, "Serveur en attente de connexions (port %d)...\n",
port);
while (online == TRUE) {
sleep (1);
/* Attente d'une connexion */
socket_service = accept (socket_ecoute, (struct sockaddr *) &adresse,
&lg_adresse);
/* SIGPIPE */
if ( (socket_service == -1) && (errno == EINTR) ) continue;
/* PAS DE CONNEXION => mode non bloquant pour attendre un ordre de
* terminaison
*/
if ( (socket_service == -1) && (errno == EAGAIN) ) continue;
/* Autre erreur socket */
if (socket_service == -1) {
/* Erreur */
printlog (LOG_ERROR,
"Erreur d'acceptation de socket, errno = %d.\n",
errno);
perror (__FILE__ " accept");
close (socket_ecoute);
return -1;
}
/* Ici connexion acceptée */
printlog (LOG_NOTIFY, "Connexion acceptée...\n");
/* Lancement d'une activité de traitement */
if (pthread_create (&pthread_id, NULL/*pthread_attr_default*/,
(void *) thread_service,
(void *) &socket_service) == -1) {
printlog (LOG_ERROR, "Erreur création thread de service.\n");
close (socket_service);
}
/* fflush (logfile); */
sleep (2);
}
printlog (LOG_NOTIFY, "Arrêt du serveur demandé.\n");
/* fflush (logfile); */
close (socket_ecoute);
free_list (&clients_list);
free_list (&drinks_list);
pthread_mutex_destroy (&mutex_broadcast);
pthread_mutex_destroy (&mutex_clients);
return 0;
}

+ 37
- 0
guinnessd.h View File

@ -0,0 +1,37 @@
/*
* guinnessd
* architecture clients/serveur guinness
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNESS_SERVER
#define GUINNESS_SERVER
#include <pthread.h>
#define CONFIG_FILE "/etc/guinnessdrc"
#define ECRITURE 0
#define LECTURE 1
typedef struct userinfos {
char nom[MAXSTRLEN + 1];
char prefb[MAXSTRLEN + 1];
char logout[MAXSTRLEN + 1];
char cxdate[MAXSTRLEN + 1];
char host[MAXSTRLEN + 1];
char ip[MAXSTRLEN + 1];
int port;
int admin;
int cold;
int comm[2]; /* Pas encore utilisé */
} userinfos;
pthread_mutex_t mutex_broadcast;
pthread_mutex_t mutex_clients;
#endif

+ 27
- 0
lists.h View File

@ -0,0 +1,27 @@
/*
* lists
* architecture clients/serveur guinness
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNESS_LISTS
#define GUINNESS_LISTS
typedef struct elt_t_ {
char *nom;
struct elt_t_ *next;
} Elt;
void add_elt (Elt **elt, const char *nom);
void remove_elt (Elt **elt, const char *nom);
void remove_elt_n (Elt **elt, int i);
int get_nb_elts (Elt *elt);
char *elt_number (Elt *elt, int i);
int exist_elt (Elt *elt, const char *nom);
char *get_elt (Elt *elt, const char *nom);
void free_list (Elt **elt);
#endif

+ 18
- 0
printlog.h View File

@ -0,0 +1,18 @@
/*
* printlog
* architecture clients/serveur guinness
* Thomas Nemeth / Arnaud Giersch -- le 23 août 2001
*
*/
#ifndef PRINT_LOGS
#define PRINT_LOGS
enum log_level {LOG_NOTIFY, LOG_ERROR};
typedef enum log_level log_level;
void printlog (log_level loglevel, const char *format, ...);
#endif

+ 20
- 0
tools.h View File

@ -0,0 +1,20 @@
/*
* tools
* Création et manipulation de sockets
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef SOCKETS_TOOLS
#define SOCKETS_TOOLS
#include <netinet/in.h>
int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse);
int connect_server (const char *machine, int port);
int install_server (int port, char *adr_ip, struct sockaddr_in *ptr_adresse);
int read_infos (int socket_data, char *infos);
int send_infos (int socket_data, const char *infos);
void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd);
#endif

+ 26
- 0
xmem.h View File

@ -0,0 +1,26 @@
/*
* xmem
* architecture clients/serveur guinness : gestion mémoire
* Thomas Nemeth -- le 24 août 2001
*
*/
#ifndef GUINNESS_XMEM
#define GUINNESS_XMEM
#include <string.h>
#include <strings.h>
void *xmalloc (size_t taille);
char *xstrdup (const char *chaine);
#define IS_NOT_GOOD(string) (! string || (strcmp (string, "") == 0))
#define SET_STRING(string, value) {\
if (string) free (string); \
string = xstrdup (value); }
#endif

Loading…
Cancel
Save