Compare commits
3 Commits
56a7863884
...
236e274656
Author | SHA1 | Date | |
---|---|---|---|
|
236e274656 | ||
|
0040d27acc | ||
|
5e17585bea |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
*.o
|
*.o
|
||||||
|
|
||||||
|
guinnessd
|
||||||
|
|
||||||
|
39
Makefile
39
Makefile
@ -9,11 +9,46 @@ H_DEP = broadcast.h commands.h defines.h guinnessd.h printlog.h \
|
|||||||
|
|
||||||
COPT = -Wall -g
|
COPT = -Wall -g
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
D_OBJS = xmem.o broadcast.o printlog.o lists.o tools.o drinks.o \
|
||||||
|
commands.o clients.o
|
||||||
|
|
||||||
guinnessd.o: guinnessd.c Makefile
|
D_LIBS = -lpthread -lcrypt
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Main program
|
||||||
|
#
|
||||||
|
|
||||||
|
guinnessd: guinnessd.o Makefile $(D_OBJS)
|
||||||
|
gcc -g $< $(D_OBJS) $(D_LIBS) -o $@
|
||||||
|
|
||||||
|
guinnessd.o: guinnessd.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
#
|
||||||
|
# modules needed by the daemon
|
||||||
|
#
|
||||||
|
|
||||||
|
broadcast.o: broadcast.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
printlog.o: printlog.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
lists.o: lists.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
xmem.o: xmem.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
tools.o: tools.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
drinks.o: drinks.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
commands.o: commands.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
clients.o: clients.c Makefile $(H_DEP)
|
||||||
gcc $(COPT) -c $<
|
gcc $(COPT) -c $<
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
clients.o: clients.c Makefile $(H_DEP)
|
||||||
|
gcc $(COPT) -c $<
|
||||||
|
|
||||||
|
274
broadcast.c
Normal file
274
broadcast.c
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
* guinnessd
|
||||||
|
* architecture clients/serveur guinness : broadcast messages
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "printlog.h"
|
||||||
|
#include "xmem.h"
|
||||||
|
#include "guinnessd.h"
|
||||||
|
#include "lists.h"
|
||||||
|
#include "tools.h"
|
||||||
|
#include "broadcast.h"
|
||||||
|
#include "drinks.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern Elt *clients_list;
|
||||||
|
extern FILE *outerr;
|
||||||
|
|
||||||
|
|
||||||
|
static int count = 0;
|
||||||
|
static unsigned long id = 0;
|
||||||
|
static Elt *bdcast_list = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long get_first_id () {
|
||||||
|
unsigned long ret = id;
|
||||||
|
|
||||||
|
if (bdcast_list) {
|
||||||
|
char *first_msg;
|
||||||
|
first_msg = elt_number (bdcast_list, 0);
|
||||||
|
ret = strtoul (first_msg, (char **)NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long get_last_id () {
|
||||||
|
unsigned long ret = id;
|
||||||
|
|
||||||
|
if (bdcast_list) {
|
||||||
|
char *last_msg;
|
||||||
|
last_msg = elt_number (bdcast_list, get_nb_elts (bdcast_list) - 1);
|
||||||
|
ret = strtoul (last_msg, (char **)NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void next_broadcast (int new) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printlog (LOG_NOTIFY, "Suivant ? (%ld restants / %s)\n",
|
||||||
|
get_nb_elts (bdcast_list), new ? "NEW" : "SUITE");
|
||||||
|
#endif
|
||||||
|
if ( (new && (get_nb_elts (bdcast_list) == 1) ) ||
|
||||||
|
( (!new) && (get_nb_elts (bdcast_list) >= 1) ) ) {
|
||||||
|
pthread_mutex_lock (&mutex_clients);
|
||||||
|
count = get_nb_elts (clients_list);
|
||||||
|
pthread_mutex_unlock (&mutex_clients);
|
||||||
|
id = get_last_id ();
|
||||||
|
#ifdef DEBUG
|
||||||
|
printlog (LOG_NOTIFY, "Message en lisse (id = %ld / count = %d)...\n",
|
||||||
|
id, count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int broadcast (int t, const char *f, const char *m) {
|
||||||
|
int taille;
|
||||||
|
char sid[MAXSTRLEN];
|
||||||
|
char stype[MAXSTRLEN];
|
||||||
|
char *message;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_clients);
|
||||||
|
if (get_nb_elts (clients_list) == 0) {
|
||||||
|
pthread_mutex_unlock (&mutex_clients);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock (&mutex_clients);
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_broadcast);
|
||||||
|
|
||||||
|
memset (sid, 0, MAXSTRLEN);
|
||||||
|
memset (stype, 0, MAXSTRLEN);
|
||||||
|
snprintf (sid, MAXSTRLEN - 1, "%ld", get_last_id () + 1);
|
||||||
|
snprintf (stype, MAXSTRLEN - 1, "%d", t);
|
||||||
|
|
||||||
|
taille = (strlen (sid) +
|
||||||
|
strlen (stype) +
|
||||||
|
(f ? strlen (f) : 3) +
|
||||||
|
(m ? strlen (m) : 0) +
|
||||||
|
5) * sizeof (char);
|
||||||
|
|
||||||
|
message = xmalloc (taille);
|
||||||
|
memset (message, 0, taille);
|
||||||
|
/* i_| t_| f_| m_ */
|
||||||
|
snprintf (message, taille, "%s%s%s%s%s%s%s",
|
||||||
|
sid, SEP,
|
||||||
|
stype, SEP,
|
||||||
|
f ? f : "---", SEP,
|
||||||
|
m ? m : "");
|
||||||
|
|
||||||
|
add_elt (&bdcast_list, message);
|
||||||
|
free (message);
|
||||||
|
next_broadcast (TRUE);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printlog (LOG_NOTIFY,
|
||||||
|
"Broadcast id = %s\t"
|
||||||
|
"type = %s\t"
|
||||||
|
"de = %s\n",
|
||||||
|
sid,
|
||||||
|
t == 1 ? "QUITTER" :
|
||||||
|
t == 2 ? "TOURNÉE" :
|
||||||
|
t == 3 ? "MESSAGE" : "RIEN",
|
||||||
|
f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pthread_mutex_unlock (&mutex_broadcast);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int new_message (long cid) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_broadcast);
|
||||||
|
res = (id > cid);
|
||||||
|
pthread_mutex_unlock (&mutex_broadcast);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int get_broadcastid () {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_broadcast);
|
||||||
|
res = id;
|
||||||
|
pthread_mutex_unlock (&mutex_broadcast);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void get_broadcastmsg (int *t, char **f, char **m) {
|
||||||
|
char *token, *bdcast, *saveptr;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_broadcast);
|
||||||
|
bdcast = xstrdup (elt_number (bdcast_list, 0));
|
||||||
|
pthread_mutex_unlock (&mutex_broadcast);
|
||||||
|
|
||||||
|
if (bdcast) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Broadcast tokenisation : %s\n", bdcast);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* id */
|
||||||
|
token = strtok_r (bdcast, SEP, &saveptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Reçu : ID = %s\n", token);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* type */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Reçu : TYPE = %s\n", token);
|
||||||
|
#endif
|
||||||
|
*t = atoi (token);
|
||||||
|
|
||||||
|
/* from */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Reçu : FROM = %s\n", token);
|
||||||
|
#endif
|
||||||
|
*f = NULL;
|
||||||
|
if (token) *f = xstrdup (token);
|
||||||
|
|
||||||
|
/* message */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Reçu : MESSAGE = %s\n", token);
|
||||||
|
#endif
|
||||||
|
*m = NULL;
|
||||||
|
if (token) *m = xstrdup (token);
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_broadcast);
|
||||||
|
if (count > 0) count--;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("count = %d\n", count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
remove_elt_n (&bdcast_list, 0);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Suppression du premier élément. Liste = %s\n",
|
||||||
|
bdcast_list ? "OK." : "NULL !");
|
||||||
|
#endif
|
||||||
|
next_broadcast (FALSE);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock (&mutex_broadcast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int send_broadcast (int socket_service, userinfos *infos) {
|
||||||
|
char datas[MAXSTRLEN];
|
||||||
|
char head[MAXSTRLEN];
|
||||||
|
char *from = NULL, *mesg = NULL, *breuv = NULL;
|
||||||
|
int type, cont = TRUE;
|
||||||
|
|
||||||
|
memset (datas, 0, MAXSTRLEN);
|
||||||
|
get_broadcastmsg (&type, &from, &mesg);
|
||||||
|
|
||||||
|
printlog (LOG_NOTIFY, "Broadcast pour [%s] : %s\n",
|
||||||
|
infos->nom,
|
||||||
|
type == 1 ? "QUITTER" :
|
||||||
|
type == 2 ? "TOURNÉE" :
|
||||||
|
type == 3 ? "MESSAGE" :
|
||||||
|
"ERREUR");
|
||||||
|
printlog (LOG_NOTIFY, " de [%s] : %s\n", from, mesg ? mesg : "RIEN");
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case QUITTER: /* Un utilisateur se déconnecte */
|
||||||
|
snprintf (datas, MAXSTRLEN - 1, "Déconnexion de [%s] : %s",
|
||||||
|
from, mesg);
|
||||||
|
break;
|
||||||
|
case TOURNEE: /* Tournée générale */
|
||||||
|
if (mesg == NULL) {
|
||||||
|
snprintf (head, MAXSTRLEN - 1,
|
||||||
|
" -+- Tournée générale offerte par %s ! -+-",
|
||||||
|
from);
|
||||||
|
breuv = drinks_get (infos->prefb);
|
||||||
|
} else {
|
||||||
|
snprintf (head, MAXSTRLEN - 1,
|
||||||
|
" -+- Tournée de %s offerte par %s ! -+-",
|
||||||
|
mesg, from);
|
||||||
|
breuv = drinks_get (mesg);
|
||||||
|
}
|
||||||
|
snprintf (datas, MAXSTRLEN - 1, "%s\n%s%s\n", head, breuv, head);
|
||||||
|
free (breuv);
|
||||||
|
break;
|
||||||
|
case MESSAGE: /* Message */
|
||||||
|
snprintf (datas, MAXSTRLEN - 1, "<%s> %s\n", from, mesg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printlog (LOG_ERROR, "Type de message broadcast non supporté.\n");
|
||||||
|
type = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from) free (from);
|
||||||
|
if (mesg) free (mesg);
|
||||||
|
|
||||||
|
if (type != -1) cont = send_infos (socket_service, datas);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
196
clients.c
Normal file
196
clients.c
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* clients
|
||||||
|
* architecture clients/serveur guinness : clients list
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "printlog.h"
|
||||||
|
#include "xmem.h"
|
||||||
|
#include "guinnessd.h"
|
||||||
|
#include "lists.h"
|
||||||
|
#include "tools.h"
|
||||||
|
#include "clients.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern Elt *clients_list;
|
||||||
|
|
||||||
|
void add_client (userinfos *infos) {
|
||||||
|
char *datas;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = strlen (infos->nom);
|
||||||
|
size += strlen (infos->prefb);
|
||||||
|
size += strlen (infos->cxdate);
|
||||||
|
size += strlen (infos->host);
|
||||||
|
size += strlen (infos->ip);
|
||||||
|
size += 5 * strlen (SEP) + 10;
|
||||||
|
|
||||||
|
datas = xmalloc (size + 1);
|
||||||
|
|
||||||
|
sprintf (datas, "%s%s%s%s%s%s%s%s%s%s%d",
|
||||||
|
infos->nom, SEP,
|
||||||
|
infos->prefb, SEP,
|
||||||
|
infos->cxdate, SEP,
|
||||||
|
infos->host, SEP,
|
||||||
|
infos->ip, SEP,
|
||||||
|
infos->port);
|
||||||
|
|
||||||
|
add_elt (&clients_list, datas);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Taille des éléments :\n"
|
||||||
|
"nom : %d [%s]\n"
|
||||||
|
"bière : %d [%s]\n"
|
||||||
|
"date : %d [%s]\n"
|
||||||
|
"hôte : %d [%s]\n"
|
||||||
|
"ip : %d [%s]\n",
|
||||||
|
strlen (infos->nom), infos->nom,
|
||||||
|
strlen (infos->prefb), infos->prefb,
|
||||||
|
strlen (infos->cxdate), infos->cxdate,
|
||||||
|
strlen (infos->host), infos->host,
|
||||||
|
strlen (infos->ip), infos->ip);
|
||||||
|
|
||||||
|
printf ("Ajout des infos : size = %d -- [%s]\n", size, datas);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
free (datas);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void remove_client (userinfos *infos) {
|
||||||
|
remove_elt (&clients_list, infos->nom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rename_client (userinfos *infos, const char *new_nick) {
|
||||||
|
if (exist_elt (clients_list, new_nick)) return FALSE;
|
||||||
|
remove_elt (&clients_list, infos->nom);
|
||||||
|
snprintf (infos->nom, MAXSTRLEN, "%s", new_nick);
|
||||||
|
add_client (infos);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *list_clients () {
|
||||||
|
char *list;
|
||||||
|
char *lstelt;
|
||||||
|
char *rt;
|
||||||
|
char text[MAXSTRLEN + 1];
|
||||||
|
int size;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
size = strlen ("Client(s) connecté(s) :\n");
|
||||||
|
for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
|
||||||
|
lstelt = elt_number (clients_list, i);
|
||||||
|
rt = strstr (lstelt, SEP);
|
||||||
|
strncpy (text, lstelt, rt - lstelt);
|
||||||
|
text[rt - lstelt] = 0;
|
||||||
|
size += 1 + strlen (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
list = xmalloc ((size + 1) * sizeof (char));
|
||||||
|
|
||||||
|
strcpy (list, "Client(s) connecté(s) :\n");
|
||||||
|
for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
|
||||||
|
lstelt = elt_number (clients_list, i);
|
||||||
|
rt = strstr (lstelt, SEP);
|
||||||
|
strncpy (text, lstelt, rt - lstelt);
|
||||||
|
text[rt - lstelt] = 0;
|
||||||
|
strcat (list, text);
|
||||||
|
strcat (list, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *infos_client (int admin, const char *nick) {
|
||||||
|
char *datas;
|
||||||
|
char *infos;
|
||||||
|
char *token, *use, *saveptr;
|
||||||
|
char *nom = NULL, *biere = NULL, *date = NULL;
|
||||||
|
char *host = NULL, *ip = NULL, *port = NULL;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
infos = get_elt (clients_list, nick);
|
||||||
|
if (! infos) {
|
||||||
|
datas = xmalloc (strlen (nick) + strlen (" : pseudo inconnu !\n"));
|
||||||
|
sprintf (datas, "%s : pseudo inconnu !\n", nick);
|
||||||
|
return datas;
|
||||||
|
}
|
||||||
|
|
||||||
|
use = xstrdup (infos);
|
||||||
|
|
||||||
|
/* nom */
|
||||||
|
token = strtok_r (use, SEP, &saveptr);
|
||||||
|
if (token) nom = xstrdup (token);
|
||||||
|
|
||||||
|
/* bière */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
if (token) biere = xstrdup (token);
|
||||||
|
|
||||||
|
/* date */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
if (token) date = xstrdup (token);
|
||||||
|
|
||||||
|
/* hôte */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
if (token) host = xstrdup (token);
|
||||||
|
|
||||||
|
/* ip */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
if (token) ip = xstrdup (token);
|
||||||
|
|
||||||
|
/* port */
|
||||||
|
token = strtok_r (NULL, SEP, &saveptr);
|
||||||
|
if (token) port = xstrdup (token);
|
||||||
|
|
||||||
|
size += strlen ("Pseudo : ");
|
||||||
|
size += strlen ("Bière : ");
|
||||||
|
size += strlen ("Connexion : ");
|
||||||
|
size += 1 + (nom ? strlen (nom) : 1);
|
||||||
|
size += 1 + (biere ? strlen (biere) : 1);
|
||||||
|
size += 1 + (date ? strlen (date) : 1);
|
||||||
|
if (admin) {
|
||||||
|
size += strlen ("Hôte : ");
|
||||||
|
size += strlen ("IP : ");
|
||||||
|
size += strlen ("Port : ");
|
||||||
|
size += 1 + (host ? strlen (host) : 1);
|
||||||
|
size += 1 + (ip ? strlen (ip) : 1);
|
||||||
|
size += 1 + (port ? strlen (port) : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
datas = xmalloc (size + 1);
|
||||||
|
|
||||||
|
sprintf (datas,
|
||||||
|
"Pseudo : %s\n"
|
||||||
|
"Bière : %s\n"
|
||||||
|
"Connexion : %s\n",
|
||||||
|
nom ? nom : "-",
|
||||||
|
biere ? biere : "-",
|
||||||
|
date ? date : "-");
|
||||||
|
if (admin)
|
||||||
|
sprintf (datas, "%s"
|
||||||
|
"Hôte : %s\n"
|
||||||
|
"IP : %s\n"
|
||||||
|
"Port : %s\n",
|
||||||
|
datas,
|
||||||
|
host ? host : "-",
|
||||||
|
ip ? ip : "-",
|
||||||
|
port ? port : "-");
|
||||||
|
|
||||||
|
if (nom) free (nom);
|
||||||
|
if (biere) free (biere);
|
||||||
|
if (date) free (date);
|
||||||
|
if (host) free (host);
|
||||||
|
if (ip) free (ip);
|
||||||
|
if (port) free (port);
|
||||||
|
|
||||||
|
return datas;
|
||||||
|
}
|
446
commands.c
Normal file
446
commands.c
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
/*
|
||||||
|
* commands
|
||||||
|
* architecture clients/serveur guinness
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "config.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"
|
||||||
|
|
||||||
|
|
||||||
|
extern FILE *logfile;
|
||||||
|
extern int online;
|
||||||
|
extern char *admin_passwd;
|
||||||
|
extern char *chemin;
|
||||||
|
extern Elt *clients_list;
|
||||||
|
extern Elt *drinks_list;
|
||||||
|
|
||||||
|
|
||||||
|
/* Signification des champs de commandes:
|
||||||
|
* NOM AIDE ARGS ADM INTRV FCT
|
||||||
|
*/
|
||||||
|
cmdslst cmds_srv[] = {
|
||||||
|
{"help", "cette page d'aide", FALSE, FALSE, FALSE, f_help},
|
||||||
|
{"quit", "quitter", FALSE, FALSE, FALSE, f_quit},
|
||||||
|
{"list", "liste des clients connectés", FALSE, FALSE, FALSE, f_list},
|
||||||
|
{"blist", "liste des boissons disponibles", FALSE, FALSE, FALSE, f_bevr},
|
||||||
|
{"round", "tournée générale (boisson en option ou préférée)",
|
||||||
|
TRUE, FALSE, FALSE, f_turn},
|
||||||
|
{"cold", "la guinness est servie à - de 10°C, sinon entre 12 et 15",
|
||||||
|
FALSE, FALSE, FALSE, f_cold},
|
||||||
|
{"msg", "message à tous les clients", TRUE, FALSE, FALSE, f_mesg},
|
||||||
|
{"infos", "renvoie les infos du serveur", TRUE, FALSE, FALSE, f_info},
|
||||||
|
{"nick", "change de pseudo", TRUE, FALSE, FALSE, f_nick},
|
||||||
|
{"123456789", "nombre de verres à recevoir (boisson en option ou "
|
||||||
|
"préférée)", FALSE, FALSE, TRUE, f_glas},
|
||||||
|
{"admin", "passer en mode administration", TRUE, FALSE, FALSE, f_sadm},
|
||||||
|
{"33", "arrêter le serveur", FALSE, TRUE, FALSE, f_shut},
|
||||||
|
{"add", "ajoute un utilisateur dans la liste des habitués",
|
||||||
|
TRUE, TRUE, FALSE, f_addu},
|
||||||
|
{"del", "enlève un utilisateur de la liste des habitués",
|
||||||
|
TRUE, TRUE, FALSE, f_delu},
|
||||||
|
{"rldb", "recharge la liste des boissons", FALSE, TRUE, FALSE, f_rldb},
|
||||||
|
{"save", "sauve la liste des habitués", FALSE, TRUE, FALSE, f_save},
|
||||||
|
{"load", "charge la liste des habitués", FALSE, TRUE, FALSE, f_load},
|
||||||
|
{NULL, NULL, FALSE, FALSE, FALSE, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int security_ok (cmdslst cmd, userinfos infos) {
|
||||||
|
return ( (cmd.adm == FALSE) ||
|
||||||
|
( (cmd.adm == TRUE) && (infos.admin == TRUE) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int reply (int socket_service, char *commande, userinfos *infos) {
|
||||||
|
int i, cont = TRUE, found = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/* Tout d'abord, on remplace \n par \0 ! */
|
||||||
|
for (i = 0 ; i <= strlen (commande) ; i++)
|
||||||
|
if ( (commande[i] == '\n') || (commande[i] == '\r') ) {
|
||||||
|
commande[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp (commande, "admin ", 6) != 0)
|
||||||
|
printlog (LOG_NOTIFY, "Commande de %s : [%s] (%d)\n",
|
||||||
|
infos->nom,
|
||||||
|
commande,
|
||||||
|
strlen (commande) );
|
||||||
|
else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printlog (LOG_NOTIFY, "Commande de %s : [%s]\n", infos->nom, commande);
|
||||||
|
#else
|
||||||
|
printlog (LOG_NOTIFY, "Commande de %s : admin XXXXXX\n", infos->nom);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush (logfile);
|
||||||
|
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||||
|
int cmp = -1;
|
||||||
|
cmdslst cmd = cmds_srv[i];
|
||||||
|
|
||||||
|
if ( (cmd.interv) &&
|
||||||
|
( (strlen (commande) == 1) ||
|
||||||
|
(commande[1] == ' ') ) ) {
|
||||||
|
cmp = strchr (cmd.nom, commande[0]) == NULL ? -1 : 0;
|
||||||
|
} else {
|
||||||
|
if (cmd.args)
|
||||||
|
cmp = strncmp (commande, cmd.nom, strlen (cmd.nom) );
|
||||||
|
else
|
||||||
|
cmp = strcmp (commande, cmd.nom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (cmp == 0) && (security_ok (cmd, *infos) == TRUE ) ) {
|
||||||
|
found = TRUE;
|
||||||
|
printlog (LOG_NOTIFY, "Commande reconnue : %s\n", cmd.nom);
|
||||||
|
cont = cmd.fct (socket_service, commande, infos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! found)
|
||||||
|
send_infos (socket_service, "Don't flood me with stupidities !\n");
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int send_servercmds (int socket_service) {
|
||||||
|
char *data;
|
||||||
|
char cmd[MAXSTRLEN];
|
||||||
|
int size = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||||
|
memset (cmd, 0, MAXSTRLEN);
|
||||||
|
if (cmds_srv[i].adm)
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
|
||||||
|
else if (cmds_srv[i].interv)
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
|
||||||
|
else
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
|
||||||
|
size += strlen (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = xmalloc ((size + 1) * sizeof (char));
|
||||||
|
strcpy (data, "");
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||||
|
memset (cmd, 0, MAXSTRLEN);
|
||||||
|
if (cmds_srv[i].adm)
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
|
||||||
|
else if (cmds_srv[i].interv)
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
|
||||||
|
else
|
||||||
|
snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
|
||||||
|
strcat (data, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return send_infos (socket_service, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_help (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
char *data;
|
||||||
|
char ligne[MAXSTRLEN];
|
||||||
|
int size = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset (ligne, 0, MAXSTRLEN);
|
||||||
|
size = strlen ("Commandes (précédées du caractère de commande) :\n");
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||||
|
if (security_ok (cmds_srv[i], *infos) == TRUE) {
|
||||||
|
if (cmds_srv[i].args)
|
||||||
|
snprintf (ligne, MAXSTRLEN - 1, " %s [opts]\t: %s\n",
|
||||||
|
cmds_srv[i].nom, cmds_srv[i].aide);
|
||||||
|
else
|
||||||
|
snprintf (ligne, MAXSTRLEN - 1, " %s%s: %s\n",
|
||||||
|
cmds_srv[i].nom,
|
||||||
|
strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
|
||||||
|
cmds_srv[i].aide);
|
||||||
|
size += strlen (ligne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data = xmalloc ((size + 1) * sizeof (char));
|
||||||
|
|
||||||
|
strcpy (data, "Commandes (précédées du caractère de commande) :\n");
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||||
|
if (security_ok (cmds_srv[i], *infos) == TRUE) {
|
||||||
|
if (cmds_srv[i].args)
|
||||||
|
snprintf (ligne, MAXSTRLEN - 1, " %s [opts]\t: %s\n",
|
||||||
|
cmds_srv[i].nom, cmds_srv[i].aide);
|
||||||
|
else
|
||||||
|
snprintf (ligne, MAXSTRLEN - 1, " %s%s: %s\n",
|
||||||
|
cmds_srv[i].nom,
|
||||||
|
strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
|
||||||
|
cmds_srv[i].aide);
|
||||||
|
strcat (data, ligne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return send_infos (socket_service, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_quit (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_list (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
char *data;
|
||||||
|
int cont;
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_clients);
|
||||||
|
data = list_clients ();
|
||||||
|
pthread_mutex_unlock (&mutex_clients);
|
||||||
|
|
||||||
|
cont = send_infos (socket_service, data);
|
||||||
|
free (data);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_bevr (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
char *data;
|
||||||
|
int size = 0;
|
||||||
|
int i;
|
||||||
|
int cont;
|
||||||
|
|
||||||
|
size = strlen ("Boissons disponibles :\n");
|
||||||
|
for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
|
||||||
|
size += strlen (elt_number (drinks_list, i) );
|
||||||
|
size += strlen ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
data = xmalloc ((size + 1) * sizeof (char));
|
||||||
|
|
||||||
|
strcpy (data, "Boissons disponibles :\n");
|
||||||
|
for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
|
||||||
|
strcat (data, elt_number (drinks_list, i) );
|
||||||
|
strcat (data, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cont = send_infos (socket_service, data);
|
||||||
|
free (data);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_cold (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont;
|
||||||
|
|
||||||
|
if (infos->cold == TRUE) {
|
||||||
|
infos->cold = FALSE;
|
||||||
|
cont = send_infos (socket_service, "Température normale.\n");
|
||||||
|
} else {
|
||||||
|
infos->cold = TRUE;
|
||||||
|
cont = send_infos (socket_service, "Température fraîche (10°C).\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_turn (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont = TRUE;
|
||||||
|
char *breuv = NULL;
|
||||||
|
|
||||||
|
if (strlen (commande) > 5) breuv = xstrdup (commande+6);
|
||||||
|
|
||||||
|
printlog (LOG_NOTIFY, "Breuvage pour tournée : %s\n",
|
||||||
|
breuv ? breuv : "préféré");
|
||||||
|
|
||||||
|
if ( ( (breuv != NULL) && (exist_elt (drinks_list, breuv) == TRUE) ) ||
|
||||||
|
(breuv == NULL) ) {
|
||||||
|
if (! broadcast (TOURNEE, infos->nom, breuv) )
|
||||||
|
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||||
|
} else
|
||||||
|
cont = send_infos (socket_service, "Boisson non disponible !\n");
|
||||||
|
|
||||||
|
free (breuv);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int f_mesg (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont = TRUE;
|
||||||
|
|
||||||
|
if (! broadcast (MESSAGE, infos->nom, commande + 4) )
|
||||||
|
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_info (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont = TRUE;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
if (strlen (commande) == 5) {
|
||||||
|
data = xmalloc (MAXSTRLEN + 1);
|
||||||
|
snprintf (data, MAXSTRLEN, "guinnessd - v %s (compilation %s : %s)\n",
|
||||||
|
VERSION, OS_TYPE, COMPIL_DATE);
|
||||||
|
} else
|
||||||
|
data = infos_client (infos->admin, commande + 6);
|
||||||
|
|
||||||
|
cont = send_infos (socket_service, data);
|
||||||
|
|
||||||
|
free (data);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_nick (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont = TRUE, rename_ok;
|
||||||
|
char *new_nick, *old_nick;
|
||||||
|
|
||||||
|
old_nick = xstrdup (infos->nom);
|
||||||
|
new_nick = xstrdup (commande + 5);
|
||||||
|
|
||||||
|
pthread_mutex_lock (&mutex_clients);
|
||||||
|
rename_ok = rename_client (infos, new_nick);
|
||||||
|
pthread_mutex_unlock (&mutex_clients);
|
||||||
|
|
||||||
|
if (rename_ok) {
|
||||||
|
char texte[MAXSTRLEN + 1];
|
||||||
|
snprintf (texte, MAXSTRLEN, "%s s'appelle maintenant %s.\n",
|
||||||
|
old_nick, new_nick);
|
||||||
|
if (! broadcast (MESSAGE, NULL, texte) )
|
||||||
|
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||||
|
} else {
|
||||||
|
cont = send_infos (socket_service, "Pseudo déjà utilisé !\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
free (old_nick);
|
||||||
|
free (new_nick);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_glas (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int i, nb, cont = TRUE;
|
||||||
|
char *breuv;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
if (strlen (commande) > 2)
|
||||||
|
breuv = xstrdup (commande + 2);
|
||||||
|
else
|
||||||
|
breuv = xstrdup (infos->prefb);
|
||||||
|
|
||||||
|
printlog (LOG_NOTIFY, "Breuvage désiré : %s\n", breuv);
|
||||||
|
|
||||||
|
data = drinks_get (breuv);
|
||||||
|
nb = atoi (commande);
|
||||||
|
for (i = 0 ; i < nb ; i++)
|
||||||
|
if ( (cont = send_infos (socket_service, data) ) == FALSE) break;
|
||||||
|
free (data);
|
||||||
|
free (breuv);
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_sadm (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
int cont = TRUE;
|
||||||
|
|
||||||
|
if ( (admin_passwd) && (strcmp (admin_passwd, commande + 6) == 0) ) {
|
||||||
|
char message[] = "Vous êtes maintenant ADMINISTRATEUR.\n"
|
||||||
|
"Nouvelles commandes :";
|
||||||
|
char *data;
|
||||||
|
int size = 0, i;
|
||||||
|
|
||||||
|
infos->admin = TRUE;
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
|
||||||
|
if (cmds_srv[i].adm) size += 1 + strlen (cmds_srv[i].nom);
|
||||||
|
|
||||||
|
size += strlen (message);
|
||||||
|
data = xmalloc ((size + 1) * sizeof (char));
|
||||||
|
memset (data, 0, size);
|
||||||
|
|
||||||
|
strcpy (data, message);
|
||||||
|
for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
|
||||||
|
if (cmds_srv[i].adm) {
|
||||||
|
strcat (data, " ");
|
||||||
|
strcat (data, cmds_srv[i].nom);
|
||||||
|
}
|
||||||
|
|
||||||
|
cont = send_infos (socket_service, data);
|
||||||
|
free (data);
|
||||||
|
} else {
|
||||||
|
infos->admin = FALSE;
|
||||||
|
cont = send_infos (socket_service,
|
||||||
|
"Vous n'êtes PLUS administrateur.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_shut (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
|
||||||
|
online = FALSE;
|
||||||
|
send_infos (socket_service, "Arrêt en cours...\n");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_rldb (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
|
||||||
|
free_list (&drinks_list);
|
||||||
|
add_elt (&drinks_list, "guinness");
|
||||||
|
if (! chemin) chemin = xstrdup (DRINKS_DIR);
|
||||||
|
drinks_list_files (chemin);
|
||||||
|
drinks_display_list ();
|
||||||
|
|
||||||
|
return send_infos (socket_service, "Liste des boissons rechargée...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int f_addu (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int f_delu (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int f_save (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int f_load (int socket_service, const char *commande, userinfos *infos) {
|
||||||
|
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||||
|
}
|
126
drinks.c
Normal file
126
drinks.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* drinks
|
||||||
|
* architecture clients/serveur guinness
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "xmem.h"
|
||||||
|
#include "printlog.h"
|
||||||
|
#include "lists.h"
|
||||||
|
#include "drinks.h"
|
||||||
|
#include "pint.h"
|
||||||
|
|
||||||
|
extern char *pinte;
|
||||||
|
extern char *chemin;
|
||||||
|
extern Elt *drinks_list;
|
||||||
|
extern FILE *logfile;
|
||||||
|
extern FILE *outerr;
|
||||||
|
|
||||||
|
|
||||||
|
char *drinks_get_from_file (const char *nom) {
|
||||||
|
struct stat fileinfos;
|
||||||
|
char filename[MAXSTRLEN + 1];
|
||||||
|
char *datas;
|
||||||
|
FILE *fichier;
|
||||||
|
|
||||||
|
snprintf (filename, MAXSTRLEN, "%s/%s", chemin, nom);
|
||||||
|
if (stat (filename, &fileinfos) == -1) {
|
||||||
|
printlog (LOG_ERROR, "Accès impossible au fichier [%s]\n",
|
||||||
|
filename);
|
||||||
|
perror ("stat ");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (fichier = fopen (filename, "r")) == NULL) return NULL;
|
||||||
|
datas = xmalloc ((fileinfos.st_size + 3) * sizeof (char));
|
||||||
|
memset (datas, 0, fileinfos.st_size + 3);
|
||||||
|
fread (datas, sizeof (char), fileinfos.st_size, fichier);
|
||||||
|
fclose (fichier);
|
||||||
|
|
||||||
|
return datas;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *drinks_get (const char *nom) {
|
||||||
|
char *breuvage = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (nom == NULL) return NULL;
|
||||||
|
|
||||||
|
/* Élément 0 (Guinness) disponible par défaut */
|
||||||
|
if (strcmp (nom, "guinness") == 0) breuvage = xstrdup (pinte);
|
||||||
|
|
||||||
|
/* Sinon on cherche dans la liste des fichiers :
|
||||||
|
* on commence à 1 pour éviter la pinte de Guinness qui est traitée
|
||||||
|
* juste avant.
|
||||||
|
*/
|
||||||
|
if (! breuvage) {
|
||||||
|
for (i = 1 ; i < get_nb_elts (drinks_list) ; i++)
|
||||||
|
if (strcmp (nom, elt_number (drinks_list, i)) == 0)
|
||||||
|
breuvage = drinks_get_from_file (nom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dernier cas : on n'a rien trouvé => pinte par défaut */
|
||||||
|
if (! breuvage) breuvage = xstrdup (pinte);
|
||||||
|
|
||||||
|
return breuvage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drinks_list_files (const char *path) {
|
||||||
|
DIR *rep;
|
||||||
|
struct dirent *dirinfos;
|
||||||
|
struct stat fileinfos;
|
||||||
|
int nbfiles = 0;
|
||||||
|
char filename[MAXSTRLEN + 1];
|
||||||
|
|
||||||
|
if ( (rep = opendir (path)) == NULL) {
|
||||||
|
printlog (LOG_ERROR, "Impossible d'ouvrir le répertoire [%s]\n", path);
|
||||||
|
#ifdef DEBUG
|
||||||
|
perror ("opendir ");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printlog (LOG_NOTIFY, "Liste des fichiers à intégrer :\n");
|
||||||
|
while ((dirinfos = readdir (rep)) != NULL) {
|
||||||
|
snprintf (filename, MAXSTRLEN, "%s/%s", path, dirinfos->d_name);
|
||||||
|
if (stat (filename, &fileinfos) == -1) {
|
||||||
|
printlog (LOG_ERROR, "Accès impossible au fichier [%s]\n",
|
||||||
|
filename);
|
||||||
|
#ifdef DEBUG
|
||||||
|
perror ("stat ");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ( (dirinfos->d_name[0] != '.') &&
|
||||||
|
( (fileinfos.st_mode & S_IFMT) == S_IFREG) ) {
|
||||||
|
printlog (LOG_NOTIFY, " fichier : [%s]\n",
|
||||||
|
dirinfos->d_name);
|
||||||
|
add_elt (&drinks_list, dirinfos->d_name);
|
||||||
|
nbfiles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printlog (LOG_NOTIFY, "Fin de la liste : %d fichier%s.\n",
|
||||||
|
nbfiles, nbfiles > 1 ? "s" : "");
|
||||||
|
closedir (rep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void drinks_display_list () {
|
||||||
|
int i;
|
||||||
|
char *breuvage;
|
||||||
|
|
||||||
|
printlog (LOG_NOTIFY, "Boissons disponibles :\n");
|
||||||
|
for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
|
||||||
|
breuvage = elt_number (drinks_list, i);
|
||||||
|
printlog (LOG_NOTIFY, "%d\t: %s\n", i, breuvage);
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@
|
|||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/* Config spécifique serveur */
|
/* Config specifique serveur */
|
||||||
char *adr_ip = NULL;
|
char *adr_ip = NULL;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
int online = TRUE;
|
int online = TRUE;
|
||||||
@ -45,7 +45,7 @@ FILE *outerr = NULL;
|
|||||||
Elt *clients_list = NULL;
|
Elt *clients_list = NULL;
|
||||||
Elt *drinks_list = NULL;
|
Elt *drinks_list = NULL;
|
||||||
|
|
||||||
/* Config spécifique connexion des clients */
|
/* Config specifique connexion des clients */
|
||||||
char *pseudo = NULL;
|
char *pseudo = NULL;
|
||||||
char *drink = NULL;
|
char *drink = NULL;
|
||||||
char *logout = NULL;
|
char *logout = NULL;
|
||||||
@ -315,7 +315,7 @@ int initiate (int socket_service, userinfos *infos) {
|
|||||||
|
|
||||||
pthread_mutex_lock (&mutex_clients);
|
pthread_mutex_lock (&mutex_clients);
|
||||||
if (exist_elt (clients_list, infos->nom)) {
|
if (exist_elt (clients_list, infos->nom)) {
|
||||||
char nick_ok[MAXSTRLEN];
|
char nick_ok[MAXSTRLEN+1];
|
||||||
snprintf (nick_ok, MAXSTRLEN, "@%s", infos->nom);
|
snprintf (nick_ok, MAXSTRLEN, "@%s", infos->nom);
|
||||||
snprintf (infos->nom, MAXSTRLEN, "%s", nick_ok);
|
snprintf (infos->nom, MAXSTRLEN, "%s", nick_ok);
|
||||||
send_infos (socket_service, "@Pseudo déjà utilisé !\n");
|
send_infos (socket_service, "@Pseudo déjà utilisé !\n");
|
||||||
@ -504,7 +504,7 @@ void guinnessd_init (int argc, char *argv[]) {
|
|||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
int socket_ecoute;
|
int socket_ecoute;
|
||||||
int socket_service;
|
int socket_service;
|
||||||
int lg_adresse = sizeof (struct sockaddr_in);
|
socklen_t lg_adresse = sizeof (struct sockaddr_in);
|
||||||
struct sockaddr_in adresse;
|
struct sockaddr_in adresse;
|
||||||
pthread_t pthread_id;
|
pthread_t pthread_id;
|
||||||
|
|
||||||
|
187
lists.c
Normal file
187
lists.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* lists
|
||||||
|
* architecture clients/serveur guinness
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "xmem.h"
|
||||||
|
#include "lists.h"
|
||||||
|
|
||||||
|
|
||||||
|
void add_elt (Elt **elt, const char *nom) {
|
||||||
|
Elt *e;
|
||||||
|
|
||||||
|
if (*elt == NULL) {
|
||||||
|
*elt = xmalloc ((1) * sizeof (Elt));
|
||||||
|
(*elt)->nom = xstrdup (nom);
|
||||||
|
(*elt)->next = NULL;
|
||||||
|
} else {
|
||||||
|
e = *elt;
|
||||||
|
while (e->next != NULL) e = e->next;
|
||||||
|
e->next = xmalloc ((1) * sizeof (Elt));
|
||||||
|
e = e->next;
|
||||||
|
e->nom = xstrdup (nom);
|
||||||
|
e->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void remove_elt (Elt **elt, const char *nom) {
|
||||||
|
Elt *e = *elt, *p = NULL;
|
||||||
|
int res = FALSE;
|
||||||
|
char *rt, *text ;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (e != NULL) {
|
||||||
|
if ((rt = strstr (e->nom, SEP)) != NULL) {
|
||||||
|
text = xmalloc (rt - e->nom + 2);
|
||||||
|
memset (text, 0, rt - e->nom + 2);
|
||||||
|
strncpy (text, e->nom, rt - e->nom);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (text, nom) == 0);
|
||||||
|
free (text);
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (e->nom, nom) == 0);
|
||||||
|
}
|
||||||
|
if (res == FALSE) {
|
||||||
|
p = e;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ( (e != NULL) && (res != TRUE) );
|
||||||
|
|
||||||
|
if (e == NULL) return;
|
||||||
|
if (e == *elt) *elt = e->next;
|
||||||
|
if (p) p->next = e->next;
|
||||||
|
free (e->nom);
|
||||||
|
free (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void remove_elt_n (Elt **elt, int i) {
|
||||||
|
Elt *e = *elt, *p = NULL;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while ( (e != NULL) && (n != i) ) {
|
||||||
|
n++;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
if (e == NULL) return;
|
||||||
|
if (e == *elt) *elt = e->next;
|
||||||
|
if (p) p->next = e->next;
|
||||||
|
free (e->nom);
|
||||||
|
free (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int get_nb_elts (Elt *elt) {
|
||||||
|
Elt *e = elt;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while (e != NULL) {
|
||||||
|
n++;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *elt_number (Elt *elt, int i) {
|
||||||
|
Elt *e = elt;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while ( (e != NULL) && (n != i) ) {
|
||||||
|
n++;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
if (e == NULL) return NULL;
|
||||||
|
|
||||||
|
return e->nom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int exist_elt (Elt *elt, const char *nom) {
|
||||||
|
Elt *e = elt;
|
||||||
|
int res = FALSE;
|
||||||
|
char *rt, *text ;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (e != NULL) {
|
||||||
|
if ((rt = strstr (e->nom, SEP)) != NULL) {
|
||||||
|
text = xmalloc (rt - e->nom + 2);
|
||||||
|
memset (text, 0, rt - e->nom + 2);
|
||||||
|
strncpy (text, e->nom, rt - e->nom);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (text, nom) == 0);
|
||||||
|
free (text);
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (e->nom, nom) == 0);
|
||||||
|
}
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
} while ( (e != NULL) && (res != TRUE) );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *get_elt (Elt *elt, const char *nom) {
|
||||||
|
Elt *e = elt;
|
||||||
|
int res = FALSE;
|
||||||
|
char *rt, *text ;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (e != NULL) {
|
||||||
|
if ((rt = strstr (e->nom, SEP)) != NULL) {
|
||||||
|
text = xmalloc (rt - e->nom + 2);
|
||||||
|
memset (text, 0, rt - e->nom + 2);
|
||||||
|
strncpy (text, e->nom, rt - e->nom);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (text, nom) == 0);
|
||||||
|
free (text);
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
|
||||||
|
#endif
|
||||||
|
res = (strcmp (e->nom, nom) == 0);
|
||||||
|
}
|
||||||
|
if (res == FALSE) e = e->next;
|
||||||
|
}
|
||||||
|
} while ( (e != NULL) && (res != TRUE) );
|
||||||
|
|
||||||
|
if (e == NULL) return NULL;
|
||||||
|
|
||||||
|
return e->nom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void free_list (Elt **elt) {
|
||||||
|
Elt *e = *elt, *p;
|
||||||
|
|
||||||
|
while (e != NULL) {
|
||||||
|
p = e;
|
||||||
|
e = e->next;
|
||||||
|
free (p->nom);
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
*elt = NULL;
|
||||||
|
}
|
41
pint.h
Normal file
41
pint.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* pint
|
||||||
|
* architecture clients/serveur guinness
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GUINNESS_SERVER_PINT
|
||||||
|
#define GUINNESS_SERVER_PINT
|
||||||
|
|
||||||
|
char *pinte =
|
||||||
|
" .____,ooo____.\n"
|
||||||
|
" ,d#MMMMMMMMMMMMMMMMMM#o.\n"
|
||||||
|
" |MMMMMMMMMMMMMMMMMMMMMMMM\n"
|
||||||
|
" |MMMMMMMMMMMMMMMMMMMMMMMM\n"
|
||||||
|
" |MMMMMMMMMMMMMMMMMMH#*#**\n"
|
||||||
|
" |M'\"\"\"\"\"\"\"\"\"\"\"\"\"'`\n"
|
||||||
|
" |M.\n"
|
||||||
|
" `ML\n"
|
||||||
|
" HP ##o#\n"
|
||||||
|
" |L TMP]\n"
|
||||||
|
" M . *&' . `\n"
|
||||||
|
" |, |dL.?-\\.~b \\:^ |\n"
|
||||||
|
" `| ` ` ' `` ,\n"
|
||||||
|
" H `\n"
|
||||||
|
" |.\n"
|
||||||
|
" `| |\n"
|
||||||
|
" M ,'\n"
|
||||||
|
" | |\n"
|
||||||
|
" |, |\n"
|
||||||
|
" || |\n"
|
||||||
|
" J' |\n"
|
||||||
|
" M. J|\n"
|
||||||
|
" HM\\\\ -':|\n"
|
||||||
|
" `\"=+\\&#HMH#*??v/''\n"
|
||||||
|
" `\"\"\"\"`\"\"\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
54
printlog.c
Normal file
54
printlog.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* printlog
|
||||||
|
* architecture clients/serveur guinness
|
||||||
|
* Thomas Nemeth / Arnaud Giersch -- le 23 août 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifdef SunOS
|
||||||
|
#include <sys/varargs.h>
|
||||||
|
#else
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "printlog.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern FILE *outerr;
|
||||||
|
extern FILE *logfile;
|
||||||
|
|
||||||
|
|
||||||
|
void printlog (log_level loglevel, const char *format, ...) {
|
||||||
|
va_list ap;
|
||||||
|
FILE *stream = logfile;
|
||||||
|
time_t now;
|
||||||
|
struct tm *today;
|
||||||
|
char date_time[MAXSTRLEN];
|
||||||
|
|
||||||
|
va_start (ap, format);
|
||||||
|
|
||||||
|
switch (loglevel) {
|
||||||
|
case LOG_NOTIFY:
|
||||||
|
stream = logfile;
|
||||||
|
break;
|
||||||
|
case LOG_ERROR:
|
||||||
|
stream = outerr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
stream = outerr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
time (&now);
|
||||||
|
today = localtime (&now);
|
||||||
|
memset (date_time, 0, MAXSTRLEN);
|
||||||
|
strftime (date_time, MAXSTRLEN - 1, "%a %d %b %Y %T", today);
|
||||||
|
fprintf (stream, "guinnessd: %s - ", date_time);
|
||||||
|
vfprintf (stream, format, ap);
|
||||||
|
|
||||||
|
va_end (ap);
|
||||||
|
}
|
||||||
|
|
297
tools.c
Normal file
297
tools.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* tools
|
||||||
|
* Création et manipulation de sockets
|
||||||
|
* Thomas Nemeth -- le 15 juin 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "xmem.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ouverture d'une socket de type flot de données
|
||||||
|
*
|
||||||
|
* création d'une socket serveur : port != 0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
|
||||||
|
int desc_soc;
|
||||||
|
int lg_adresse = sizeof (struct sockaddr_in);
|
||||||
|
int lg_linger = sizeof (struct linger);
|
||||||
|
struct sockaddr_in adresse;
|
||||||
|
struct linger ling;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Création de la socket
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if ( (desc_soc = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Ne peut pas ouvrir la socket de connexion.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Affectation des options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (port != 0) {
|
||||||
|
int opt = 1;
|
||||||
|
if (setsockopt (desc_soc, SOL_SOCKET,
|
||||||
|
SO_REUSEADDR, &opt, sizeof (int) ) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Impossible de positionner REUSEADDR.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " setsockopt -- REUSEADDR");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ling.l_onoff = 0;
|
||||||
|
ling.l_linger = 0;
|
||||||
|
if (setsockopt (desc_soc, SOL_SOCKET, SO_LINGER, &ling, lg_linger) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Impossible de positionner LINGER.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " setsockopt -- LINGER");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Préparation de l'adresse d'attachement
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
memset (&adresse, 0, sizeof (adresse) );
|
||||||
|
adresse.sin_family = AF_INET;
|
||||||
|
if (adr_ip) {
|
||||||
|
struct in_addr ia;
|
||||||
|
|
||||||
|
if (inet_aton(adr_ip, &ia)) {
|
||||||
|
adresse.sin_addr = ia;
|
||||||
|
} else {
|
||||||
|
struct hostent *h;
|
||||||
|
|
||||||
|
h = gethostbyname(adr_ip);
|
||||||
|
if (!h) {
|
||||||
|
fprintf (stderr, "Adresse %s inconnue.\n", adr_ip);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy (&adresse.sin_addr.s_addr, h->h_addr, h->h_length);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
adresse.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
adresse.sin_port = htons (port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Demande d'attachement de la socket
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (bind (desc_soc, (struct sockaddr*) &adresse, lg_adresse) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr,
|
||||||
|
"Ne peut donner de nom à la socket de connexion.\n"
|
||||||
|
"Attendez quelques minutes avant de relancer.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " bind");
|
||||||
|
close (desc_soc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Récupération de l'adresse effective d'attachement
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (ptr_adresse != NULL)
|
||||||
|
getsockname (desc_soc, (struct sockaddr *) ptr_adresse, &lg_adresse);
|
||||||
|
|
||||||
|
return desc_soc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int connect_server (const char *machine, int port) {
|
||||||
|
struct hostent *serveur;
|
||||||
|
struct sockaddr_in adresse_serveur, adresse_client;
|
||||||
|
int socket_client;
|
||||||
|
|
||||||
|
/* Recherche de la machine où se trouve le serveur */
|
||||||
|
if ( (serveur = gethostbyname (machine) ) == NULL) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Machine %s inconnue...\n", machine);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Création et attachement de la socket du client --
|
||||||
|
* port quelconque => 0
|
||||||
|
*/
|
||||||
|
if ( (socket_client = ouvre_socket
|
||||||
|
(0, NULL, (struct sockaddr_in *) &adresse_client)) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Création de la socket du client impossible.\n");
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Préparation de l'adresse du serveur */
|
||||||
|
adresse_serveur.sin_family = AF_INET;
|
||||||
|
adresse_serveur.sin_port = htons (port);
|
||||||
|
memcpy (&adresse_serveur.sin_addr.s_addr,
|
||||||
|
serveur->h_addr, serveur->h_length);
|
||||||
|
|
||||||
|
/* Demande de connexion au serveur */
|
||||||
|
if (connect (socket_client, (struct sockaddr *) &adresse_serveur,
|
||||||
|
sizeof (adresse_serveur) ) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Impossible de se connecter au serveur.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " connect");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int install_server (int port, char *adr_ip, struct sockaddr_in *ecoute) {
|
||||||
|
int socket_ecoute;
|
||||||
|
|
||||||
|
/* Ouverture de la socket */
|
||||||
|
if ( (socket_ecoute = ouvre_socket (port, adr_ip, ecoute)) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Création de la socket du serveur impossible.\n");
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Déclaration d'ouverture du service */
|
||||||
|
if (listen (socket_ecoute, 10) == -1) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Impossible d'enregistrer le service.\n");
|
||||||
|
#endif
|
||||||
|
perror (__FILE__ " listen");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket_ecoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fonction de réception de données
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int read_infos (int socket_data, char *infos) {
|
||||||
|
int nb;
|
||||||
|
|
||||||
|
/* SSIZE_MAX = 2147483647 */
|
||||||
|
memset (infos, 0, MAXSTRLEN);
|
||||||
|
nb = read (socket_data, infos, MAXSTRLEN - 1);
|
||||||
|
|
||||||
|
if ( (nb == -1) || (nb == 0) ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Erreur de connexion réception !\n");
|
||||||
|
#endif
|
||||||
|
if ( (errno == EPIPE) || (nb == 0) ) return FALSE; /* cont = FALSE; */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Reçu : [%s] lg = %d/%d\n", infos, strlen (infos), nb);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fonction d'émisson de données
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int send_infos (int socket_data, const char *infos) {
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Émission de : %s [%d]\n", infos, strlen (infos));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (write (socket_data, (void *) infos, strlen (infos) + 1) == -1) {
|
||||||
|
/* Erreur : plus de socket ! */
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Erreur de connexion émission !\n");
|
||||||
|
#endif
|
||||||
|
if (errno == EPIPE) return FALSE; /*cont = FALSE;*/
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "Émission ok !\n");
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
|
||||||
|
struct sockaddr_in name;
|
||||||
|
#ifdef OpenBSD
|
||||||
|
int namelen;
|
||||||
|
#else
|
||||||
|
socklen_t namelen;
|
||||||
|
#endif
|
||||||
|
struct hostent *machine;
|
||||||
|
|
||||||
|
/* Initialisations en cas d'échecs */
|
||||||
|
*nom = NULL;
|
||||||
|
*adr = NULL;
|
||||||
|
*prd = 0;
|
||||||
|
|
||||||
|
/* Infos locales (port) */
|
||||||
|
namelen = sizeof (name);
|
||||||
|
if (getsockname (sock, (struct sockaddr *) &name, &namelen) == 0)
|
||||||
|
*prl = ntohs (name.sin_port);
|
||||||
|
else {
|
||||||
|
perror ("getsockname() ");
|
||||||
|
*prl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Port et adresse IP distants */
|
||||||
|
namelen = sizeof (name);
|
||||||
|
if (getpeername (sock, (struct sockaddr *) &name, &namelen) != 0) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
perror ("Erreur de récupération d'information sur pair !\n"
|
||||||
|
"getpeername() ");
|
||||||
|
#else
|
||||||
|
perror ("Impossible d'obtenir les infos distantes ");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*adr = xstrdup (inet_ntoa (name.sin_addr));
|
||||||
|
*prd = ntohs (name.sin_port);
|
||||||
|
|
||||||
|
/* Nom de machine distante */
|
||||||
|
machine = gethostbyaddr ((char *)&name.sin_addr,
|
||||||
|
sizeof name.sin_addr, name.sin_family);
|
||||||
|
if (machine == NULL) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
perror ("Erreur de récupération de nom de pair.\n"
|
||||||
|
"gethostbyaddr() ");
|
||||||
|
fprintf (stderr, "Adresse : %s (%s)\tFamille : %d (2 == AF_INET)\n",
|
||||||
|
*adr, (char *)&name.sin_addr, name.sin_family);
|
||||||
|
#else
|
||||||
|
perror ("Impossible d'obtenir le nom d'hôte distant ");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nom = xstrdup (machine->h_name);
|
||||||
|
}
|
31
xmem.c
Normal file
31
xmem.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* xmem
|
||||||
|
* architecture clients/serveur guinness : gestion mémoire
|
||||||
|
* Thomas Nemeth -- le 24 août 2001
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "xmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
void *xmalloc (size_t taille) {
|
||||||
|
void *ret = malloc (taille);
|
||||||
|
if (ret == NULL) {
|
||||||
|
perror ("malloc() ");
|
||||||
|
exit (-1);
|
||||||
|
} else
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xstrdup (const char *chaine) {
|
||||||
|
char *ret = strdup (chaine);
|
||||||
|
if (ret == NULL) {
|
||||||
|
perror ("strdup() ");
|
||||||
|
exit (-1);
|
||||||
|
} else
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user