Compare commits

..

12 Commits

Author SHA1 Message Date
mco-system
6b89f86b71 doc: fix bad encoding 2025-10-05 18:36:17 +11:00
65b4622447 Merge pull request 'docker' (#2) from docker into master
Reviewed-on: #2
2025-10-05 11:26:03 +11:00
fb0ea65c80 Merge branch 'master' into docker 2025-10-05 11:25:06 +11:00
mco-system
c313b58375 fix+doc: fix missing CMD directive in dockerfile + updated doc 2025-10-05 11:23:45 +11:00
mco-system
002154f58f fix: missing CMD in Dockerfile 2025-10-05 11:07:10 +11:00
6159b7d07e Merge pull request 'docker' (#1) from docker into master
Reviewed-on: #1
2025-10-05 10:52:27 +11:00
mco-system
58c7549e65 fix: use extern mutex and COPT -fPIE -Wno-error. Add Dockerfile 2025-10-05 10:50:44 +11:00
mco-system
25ccec2fd3 WIP: missing picoles dir 2025-10-05 10:32:35 +11:00
tonton Th
8a9dff3514 faciltate access to the drink's storage 2020-04-20 23:30:44 +02:00
tonton Th
311baad6cb asciification du code source 2020-04-14 23:41:07 +02:00
tonton Th
efeef4140b première tournée !!! 2020-03-28 15:27:55 +01:00
tonton Th
0ef949ce91 client compiled :) 2020-03-28 11:56:49 +01:00
25 changed files with 943 additions and 138 deletions

1
.gitignore vendored
View File

@@ -3,4 +3,5 @@
*.o
guinnessd
guinness

20
Dockerfile Normal file
View File

@@ -0,0 +1,20 @@
FROM debian:12 AS guinnessd-base
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y make gcc && \
useradd -m -d /home/guinness -s /bin/false -r guinness
FROM guinnessd-base
COPY . /home/guinness/src
WORKDIR /home/guinness
RUN make -C /home/guinness/src && \
mv /home/guinness/src/guinnessd /usr/local/bin && \
mv /home/guinness/src/picoles /usr/local/share && \
chmod +x /usr/local/bin/guinnessd && \
rm -Rf /home/guinness/src && \
apt-get remove -y make gcc && \
apt-get autoremove -y
USER guinness
CMD ["/usr/local/bin/guinnessd", "-p", "1664", "-d", "/usr/local/share/picoles"]

View File

@@ -4,14 +4,20 @@
# Makefile handcrafted by tTh
#
all: guinness guinnessd
# ---------------------------------------------------------
H_DEP = broadcast.h commands.h defines.h guinnessd.h printlog.h \
xmem.h clients.h config.h drinks.h lists.h tools.h
COPT = -Wall -g
COPT = -fPIE -Wno-error -g
D_OBJS = xmem.o broadcast.o printlog.o lists.o tools.o drinks.o \
commands.o clients.o
C_OBJS = xmem.o tools.o
D_LIBS = -lpthread -lcrypt
# ---------------------------------------------------------
@@ -25,6 +31,14 @@ guinnessd: guinnessd.o Makefile $(D_OBJS)
guinnessd.o: guinnessd.c Makefile $(H_DEP)
gcc $(COPT) -c $<
#
guinness: guinness.o Makefile $(D_OBJS)
gcc -g $< $(C_OBJS) $(D_LIBS) -o $@
guinness.o: guinness.c Makefile $(H_DEP)
gcc $(COPT) -c $<
# ---------------------------------------------------------
#
# modules needed by the daemon
@@ -49,6 +63,4 @@ clients.o: clients.c Makefile $(H_DEP)
# ---------------------------------------------------------
clients.o: clients.c Makefile $(H_DEP)
gcc $(COPT) -c $<

4
Makefile.docker Normal file
View File

@@ -0,0 +1,4 @@
.PHONY: build
build:
docker build -t guinnessd:latest .

125
README.md
View File

@@ -12,18 +12,139 @@ retraite sanitaire, de sortir la disqueuse et de tenter de trouver
le bug. Et ça ne va pas être simple, le Makefile d'origine est
**très** convolué...
Par la suite, j'ai l'intention d'y apporter quelques modifications
que je trouverais à mon gout. Elles seront décrites plus bas
dans la page.
## 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...
jus de citron pour le goût : importer les fichiers un à un jusqu'à ce
que ça marche. Et par la suite, remttre les choses au clair.
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.
la disqueuse, je n'ai qu'un `config.h.in` sous la main. Qu'à cela ne tienne,
_kraftons_ vite ce fichier manquant à la main.
Voilà finalement, avec cette méthode (que je n'hésite à appeler le
goutte-à-goutte), j'ai reconstitué un Makefile qui fonctionne et
compile le client et le serveur.
## Résultat :
Et voilà une session typique de remote-picole :
```
tth@lubitel:~/Devel/GuinnessServer$ ./guinnessd
guinnessd: Sat 28 Mar 2020 15:21:35 - Impossible d'ouvrir le repertoire [/var/tmp/drinks.d]
guinnessd: Sat 28 Mar 2020 15:21:35 - Boissons disponibles :
guinnessd: Sat 28 Mar 2020 15:21:35 - 0 : guinness
guinnessd: Sat 28 Mar 2020 15:21:35 - Serveur en attente de connexions (port 1664)...
guinnessd: Sat 28 Mar 2020 15:22:18 - Connexion acceptee...
guinnessd: Sat 28 Mar 2020 15:22:18 - Connexion entrante : 127.0.0.1 localhost
guinnessd: Sat 28 Mar 2020 15:22:18 - Ports (loc/dist) : 1664 / 47647
guinnessd: Sat 28 Mar 2020 15:22:18 - Utilisateur : [tth]
guinnessd: Sat 28 Mar 2020 15:22:18 - Boisson preferee : [guinness]
guinnessd: Sat 28 Mar 2020 15:22:18 - Message de logout : [Bye bye...]
guinnessd: Sat 28 Mar 2020 15:22:18 - Date de connexion : [Sat 28 Mar 2020 15:22:18]
guinnessd: Sat 28 Mar 2020 15:22:19 - Broadcast pour [tth] : MESSAGE
guinnessd: Sat 28 Mar 2020 15:22:19 - de [---] : tth a rejoint le serveur de Guinness.
```
« 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. »
```
tth@lubitel:~/Devel/GuinnessServer$ ./guinness -u tth
Serveur : [127.0.0.1] Port : [1664]
Utilisateur : [tth] Boisson : [guinness] Logout : [Bye bye...]
Préfixe : [/]
-+- Connexion acceptee. -+-
Bienvenue sur le serveur de Guinness.
> <---> tth a rejoint le serveur de Guinness.
> /1
.____,ooo____.
,d#MMMMMMMMMMMMMMMMMM#o.
|MMMMMMMMMMMMMMMMMMMMMMMM
|MMMMMMMMMMMMMMMMMMMMMMMM
|MMMMMMMMMMMMMMMMMMH#*#**
|M'"""""""""""""'`
|M.
`ML
HP ##o#
|L TMP]
M . *&' . `
|, |dL.?-\.~b \:^ |
`| ` ` ' `` ,
H `
|.
`| |
M ,'
| |
|, |
|| |
J' |
M. J|
HM\\ -':|
`"=+\&#HMH#*??v/''
`""""`""
>
```
## Modifications
* ajouter une variable d'environnement `DRINKS_DIR` pour spécifier l'emplacement
de la réserve de picole.
* modifier la gestion des fichiers de picole afin d'avoir une description
succinte dans le listing du bar.
## Conteneur
Le serveur BaaS (Beverage as a Service) est dorénavant disponible sous forme de conteneur.
### Génération de l'image
Création de l'image `guinnessd:latest`
```bash
make -f Makefile.docker build
```
### Utilisation du conteneur
- Le service écoute sur le port `1664`.
- Le bar se situe dans `/usr/local/share/picoles` et est déjà approvionné. il est donc possible d'en faire un *volume Docker*.
```bash
docker run --rm -p 1664:1664 guinnessd:latest
```
### *Docker Swarm*
Ma préférence allant à l'utilisation de *Docker* via les *Docker Swarm*, vous touverez ci-dessous un fichier de *stack*
```yaml
version: 3.9
service:
guinnessd:
image: guinnessd:latest
logging:
driver: journald
options:
tag: "docker: guinnessd"
ports:
- target: 1664
published: 1664
mode: host
deploy:
endpoint_mode: dnsrr
mode: replicated
replicas: 1 # Multipliez les barmen en ajoutant des réplicas :-)
```

View File

@@ -26,6 +26,7 @@
#include "broadcast.h"
#include "drinks.h"
pthread_mutex_t mutex_broadcast;
extern Elt *clients_list;
extern FILE *outerr;
@@ -127,7 +128,7 @@ int broadcast (int t, const char *f, const char *m) {
"de = %s\n",
sid,
t == 1 ? "QUITTER" :
t == 2 ? "TOURNÉE" :
t == 2 ? "TOURNEE" :
t == 3 ? "MESSAGE" : "RIEN",
f);
#endif
@@ -175,20 +176,20 @@ void get_broadcastmsg (int *t, char **f, char **m) {
/* id */
token = strtok_r (bdcast, SEP, &saveptr);
#ifdef DEBUG
printf ("Reçu : ID = %s\n", token);
printf ("Recu : ID = %s\n", token);
#endif
/* type */
token = strtok_r (NULL, SEP, &saveptr);
#ifdef DEBUG
printf ("Reçu : TYPE = %s\n", token);
printf ("Recu : TYPE = %s\n", token);
#endif
*t = atoi (token);
/* from */
token = strtok_r (NULL, SEP, &saveptr);
#ifdef DEBUG
printf ("Reçu : FROM = %s\n", token);
printf ("Recu : FROM = %s\n", token);
#endif
*f = NULL;
if (token) *f = xstrdup (token);
@@ -196,7 +197,7 @@ void get_broadcastmsg (int *t, char **f, char **m) {
/* message */
token = strtok_r (NULL, SEP, &saveptr);
#ifdef DEBUG
printf ("Reçu : MESSAGE = %s\n", token);
printf ("Recu : MESSAGE = %s\n", token);
#endif
*m = NULL;
if (token) *m = xstrdup (token);
@@ -210,7 +211,7 @@ void get_broadcastmsg (int *t, char **f, char **m) {
if (count == 0) {
remove_elt_n (&bdcast_list, 0);
#ifdef DEBUG
printf ("Suppression du premier élément. Liste = %s\n",
printf ("Suppression du premier element. Liste = %s\n",
bdcast_list ? "OK." : "NULL !");
#endif
next_broadcast (FALSE);
@@ -232,25 +233,25 @@ int send_broadcast (int socket_service, userinfos *infos) {
printlog (LOG_NOTIFY, "Broadcast pour [%s] : %s\n",
infos->nom,
type == 1 ? "QUITTER" :
type == 2 ? "TOURNÉE" :
type == 2 ? "TOURNEE" :
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",
case QUITTER: /* Un utilisateur se deconnecte */
snprintf (datas, MAXSTRLEN - 1, "Deconnexion de [%s] : %s",
from, mesg);
break;
case TOURNEE: /* Tournée générale */
case TOURNEE: /* Tournee generale */
if (mesg == NULL) {
snprintf (head, MAXSTRLEN - 1,
" -+- Tournée générale offerte par %s ! -+-",
" -+- Tournee generale offerte par %s ! -+-",
from);
breuv = drinks_get (infos->prefb);
} else {
snprintf (head, MAXSTRLEN - 1,
" -+- Tournée de %s offerte par %s ! -+-",
" -+- Tournee de %s offerte par %s ! -+-",
mesg, from);
breuv = drinks_get (mesg);
}
@@ -261,7 +262,7 @@ int send_broadcast (int socket_service, userinfos *infos) {
snprintf (datas, MAXSTRLEN - 1, "<%s> %s\n", from, mesg);
break;
default:
printlog (LOG_ERROR, "Type de message broadcast non supporté.\n");
printlog (LOG_ERROR, "Type de message broadcast non supporte.\n");
type = -1;
}

View File

@@ -45,11 +45,11 @@ void add_client (userinfos *infos) {
add_elt (&clients_list, datas);
#ifdef DEBUG
printf ("Taille des éléments :\n"
printf ("Taille des elements :\n"
"nom : %d [%s]\n"
"bière : %d [%s]\n"
"biere : %d [%s]\n"
"date : %d [%s]\n"
"hôte : %d [%s]\n"
"hote : %d [%s]\n"
"ip : %d [%s]\n",
strlen (infos->nom), infos->nom,
strlen (infos->prefb), infos->prefb,
@@ -86,7 +86,7 @@ char *list_clients () {
int size;
int i;
size = strlen ("Client(s) connecté(s) :\n");
size = strlen ("Client(s) connecte(s) :\n");
for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
lstelt = elt_number (clients_list, i);
rt = strstr (lstelt, SEP);
@@ -97,7 +97,7 @@ char *list_clients () {
list = xmalloc ((size + 1) * sizeof (char));
strcpy (list, "Client(s) connecté(s) :\n");
strcpy (list, "Client(s) connecte(s) :\n");
for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
lstelt = elt_number (clients_list, i);
rt = strstr (lstelt, SEP);
@@ -131,7 +131,7 @@ char *infos_client (int admin, const char *nick) {
token = strtok_r (use, SEP, &saveptr);
if (token) nom = xstrdup (token);
/* bière */
/* biere */
token = strtok_r (NULL, SEP, &saveptr);
if (token) biere = xstrdup (token);
@@ -139,7 +139,7 @@ char *infos_client (int admin, const char *nick) {
token = strtok_r (NULL, SEP, &saveptr);
if (token) date = xstrdup (token);
/* hôte */
/* hote */
token = strtok_r (NULL, SEP, &saveptr);
if (token) host = xstrdup (token);
@@ -152,13 +152,13 @@ char *infos_client (int admin, const char *nick) {
if (token) port = xstrdup (token);
size += strlen ("Pseudo : ");
size += strlen ("Bière : ");
size += strlen ("Biere : ");
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 ("Hote : ");
size += strlen ("IP : ");
size += strlen ("Port : ");
size += 1 + (host ? strlen (host) : 1);
@@ -170,14 +170,14 @@ char *infos_client (int admin, const char *nick) {
sprintf (datas,
"Pseudo : %s\n"
"Bière : %s\n"
"Biere : %s\n"
"Connexion : %s\n",
nom ? nom : "-",
biere ? biere : "-",
date ? date : "-");
if (admin)
sprintf (datas, "%s"
"Hôte : %s\n"
"Hote : %s\n"
"IP : %s\n"
"Port : %s\n",
datas,

View File

@@ -44,26 +44,26 @@ extern Elt *drinks_list;
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},
{"list", "liste des clients connectes", 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)",
{"round", "tournee generale (boisson en option ou preferee)",
TRUE, FALSE, FALSE, f_turn},
{"cold", "la guinness est servie à - de 10°C, sinon entre 12 et 15",
{"cold", "la guinness est servie a - de 10C, sinon entre 12 et 15",
FALSE, FALSE, FALSE, f_cold},
{"msg", "message à tous les clients", TRUE, FALSE, FALSE, f_mesg},
{"msg", "message a 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},
{"123456789", "nombre de verres a recevoir (boisson en option ou "
"preferee)", 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",
{"33", "arreter le serveur", FALSE, TRUE, FALSE, f_shut},
{"add", "ajoute un utilisateur dans la liste des habitues",
TRUE, TRUE, FALSE, f_addu},
{"del", "enlève un utilisateur de la liste des habitués",
{"del", "enleve un utilisateur de la liste des habitues",
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},
{"save", "sauve la liste des habitues", FALSE, TRUE, FALSE, f_save},
{"load", "charge la liste des habitues", FALSE, TRUE, FALSE, f_load},
{NULL, NULL, FALSE, FALSE, FALSE, NULL}
};
@@ -171,7 +171,7 @@ int f_help (int socket_service, const char *commande, userinfos *infos) {
int i;
memset (ligne, 0, MAXSTRLEN);
size = strlen ("Commandes (précédées du caractère de commande) :\n");
size = strlen ("Commandes (precedees du caractere 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)
@@ -188,7 +188,7 @@ int f_help (int socket_service, const char *commande, userinfos *infos) {
data = xmalloc ((size + 1) * sizeof (char));
strcpy (data, "Commandes (précédées du caractère de commande) :\n");
strcpy (data, "Commandes (precedees du caractere 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)
@@ -259,10 +259,10 @@ int f_cold (int socket_service, const char *commande, userinfos *infos) {
if (infos->cold == TRUE) {
infos->cold = FALSE;
cont = send_infos (socket_service, "Température normale.\n");
cont = send_infos (socket_service, "Temperature normale.\n");
} else {
infos->cold = TRUE;
cont = send_infos (socket_service, "Température fraîche (10°C).\n");
cont = send_infos (socket_service, "Temperature fraiche (10C).\n");
}
return cont;
@@ -275,8 +275,8 @@ int f_turn (int socket_service, const char *commande, userinfos *infos) {
if (strlen (commande) > 5) breuv = xstrdup (commande+6);
printlog (LOG_NOTIFY, "Breuvage pour tournée : %s\n",
breuv ? breuv : "préféré");
printlog (LOG_NOTIFY, "Breuvage pour tournee : %s\n",
breuv ? breuv : "prefere");
if ( ( (breuv != NULL) && (exist_elt (drinks_list, breuv) == TRUE) ) ||
(breuv == NULL) ) {
@@ -339,7 +339,7 @@ int f_nick (int socket_service, const char *commande, userinfos *infos) {
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");
cont = send_infos (socket_service, "Pseudo deja utilise !\n");
}
free (old_nick);
@@ -359,7 +359,7 @@ int f_glas (int socket_service, const char *commande, userinfos *infos) {
else
breuv = xstrdup (infos->prefb);
printlog (LOG_NOTIFY, "Breuvage désiré : %s\n", breuv);
printlog (LOG_NOTIFY, "Breuvage desire : %s\n", breuv);
data = drinks_get (breuv);
nb = atoi (commande);
@@ -376,7 +376,7 @@ 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"
char message[] = "Vous etes maintenant ADMINISTRATEUR.\n"
"Nouvelles commandes :";
char *data;
int size = 0, i;
@@ -401,7 +401,7 @@ int f_sadm (int socket_service, const char *commande, userinfos *infos) {
} else {
infos->admin = FALSE;
cont = send_infos (socket_service,
"Vous n'êtes PLUS administrateur.\n");
"Vous n'etes PLUS administrateur.\n");
}
return cont;
@@ -411,7 +411,7 @@ int f_sadm (int socket_service, const char *commande, userinfos *infos) {
int f_shut (int socket_service, const char *commande, userinfos *infos) {
online = FALSE;
send_infos (socket_service, "Arrêt en cours...\n");
send_infos (socket_service, "Arret en cours...\n");
return FALSE;
}
@@ -425,22 +425,22 @@ int f_rldb (int socket_service, const char *commande, userinfos *infos) {
drinks_list_files (chemin);
drinks_display_list ();
return send_infos (socket_service, "Liste des boissons rechargée...\n");
return send_infos (socket_service, "Liste des boissons rechargee...\n");
}
int f_addu (int socket_service, const char *commande, userinfos *infos) {
return send_infos (socket_service, "Fonction non implémentée...\n");
return send_infos (socket_service, "Fonction non implementee...\n");
}
int f_delu (int socket_service, const char *commande, userinfos *infos) {
return send_infos (socket_service, "Fonction non implémentée...\n");
return send_infos (socket_service, "Fonction non implementee...\n");
}
int f_save (int socket_service, const char *commande, userinfos *infos) {
return send_infos (socket_service, "Fonction non implémentée...\n");
return send_infos (socket_service, "Fonction non implementee...\n");
}
int f_load (int socket_service, const char *commande, userinfos *infos) {
return send_infos (socket_service, "Fonction non implémentée...\n");
return send_infos (socket_service, "Fonction non implementee...\n");
}

View File

@@ -24,7 +24,7 @@ typedef struct cmdslst {
int reply (int socket_service, char *commande, userinfos *infos);
int send_servercmds (int socket_service);
/* Fonctions associées aux commandes */
/* Fonctions associees 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);

View File

@@ -1,6 +1,6 @@
/*
* defines
* Création et manipulation de sockets
* Creation et manipulation de sockets
* Thomas Nemeth -- le 15 juin 2001
*
*/

View File

@@ -34,7 +34,7 @@ char *drinks_get_from_file (const char *nom) {
snprintf (filename, MAXSTRLEN, "%s/%s", chemin, nom);
if (stat (filename, &fileinfos) == -1) {
printlog (LOG_ERROR, "Accès impossible au fichier [%s]\n",
printlog (LOG_ERROR, "Acces impossible au fichier [%s]\n",
filename);
perror ("stat ");
return NULL;
@@ -56,11 +56,11 @@ char *drinks_get (const char *nom) {
if (nom == NULL) return NULL;
/* Élément 0 (Guinness) disponible par défaut */
/* Element 0 (Guinness) disponible par defaut */
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
* on commence a 1 pour eviter la pinte de Guinness qui est traitee
* juste avant.
*/
if (! breuvage) {
@@ -69,7 +69,7 @@ char *drinks_get (const char *nom) {
breuvage = drinks_get_from_file (nom);
}
/* Dernier cas : on n'a rien trouvé => pinte par défaut */
/* Dernier cas : on n'a rien trouve => pinte par defaut */
if (! breuvage) breuvage = xstrdup (pinte);
return breuvage;
@@ -83,18 +83,18 @@ void drinks_list_files (const char *path) {
char filename[MAXSTRLEN + 1];
if ( (rep = opendir (path)) == NULL) {
printlog (LOG_ERROR, "Impossible d'ouvrir le répertoire [%s]\n", path);
printlog (LOG_ERROR, "Impossible d'ouvrir le repertoire [%s]\n", path);
#ifdef DEBUG
perror ("opendir ");
#endif
return;
}
printlog (LOG_NOTIFY, "Liste des fichiers à intégrer :\n");
printlog (LOG_NOTIFY, "Liste des fichiers a integrer :\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",
printlog (LOG_ERROR, "Acces impossible au fichier [%s]\n",
filename);
#ifdef DEBUG
perror ("stat ");

529
guinness.c Normal file
View File

@@ -0,0 +1,529 @@
/*
* guinness
* architecture clients/serveur guinness.
* Thomas Nemeth -- le 15 juin 2001
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <strings.h>
#include "defines.h"
#include "xmem.h"
#include "guinness.h"
#include "tools.h"
#include "config.h"
#ifdef SunOS
char *crypt(const char *key, const char *salt);
#else
extern char *crypt __P ((__const char *__key, __const char *__salt));
#endif
/* VARIABLES GLOBALES */
char **commandes = NULL;
char *utilisateur = NULL;
char *boisson = NULL;
char *serveur = NULL;
char *prompt = NULL;
char *logout = NULL;
char cmdchr = 0;
int port = 0;
int nb_cmd = 0;
/*
* Lecture du fichier de config : recuperation 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 *configfile;
char tmpstr[MAXSTRLEN + 1];
char *Home;
char *value;
Home = getenv ("HOME");
configfile = xmalloc ((strlen (Home) +
strlen (CONFIG_FILE) + 2) * sizeof (char));
snprintf (configfile, MAXSTRLEN, "%s/%s", Home, CONFIG_FILE);
/* Ouverture du fichier */
if ( (file = fopen (configfile, "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, "user=", 5) == 0) && (utilisateur == NULL) )
utilisateur = xstrdup (value);
if ( (strncmp (tmpstr, "server=", 7) == 0) && (serveur == NULL) )
serveur = xstrdup (value);
if ( (strncmp (tmpstr, "port=", 5) == 0) && (port == 0) )
port = atoi (value);
if ( (strncmp (tmpstr, "prompt=", 7) == 0) && (prompt == NULL) )
prompt = xstrdup (value);
if ( (strncmp (tmpstr, "pref=", 5) == 0) && (boisson == NULL) )
boisson = xstrdup (value);
if ( (strncmp (tmpstr, "cmdchr=", 7) == 0) && (cmdchr == 0) )
cmdchr = value[0];
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", configfile);
#endif
}
free (configfile);
}
/*
* Fonction de nettoyage
*
*/
void libere () {
if (utilisateur) free (utilisateur);
if (serveur) free (serveur);
if (boisson) free (boisson);
if (logout) free (logout);
}
/*
* Aide
*
*/
void Usage (int help) {
printf ("guinness by Thomas Nemeth - v %s (compilation %s : %s)\n",
VERSION, OS_TYPE, COMPIL_DATE);
if (help)
printf ("Usage : guinness [-h] [-v] [-m machine] "
"[-p port] [-u utilisateur] [-b boisson] [-q msgdx]\n"
" -h : aide sur les parametres\n"
" -v : affiche la version\n"
" -m machine : speficie le nom du serveur\n"
" -p port : specifie le numero du port\n"
" -u utilisateur : nom d'utilisateur\n"
" -b boisson : boisson preferee\n"
" -q msgdx : message d'au-revoir a la deconnexion\n"
" Online (precede du caractere de commande \"/\") :\n"
" help : affiche l'aide sur les commandes\n"
" quit : quitte\n\n");
libere ();
exit (1);
}
/*
* Traitement des arguments
*
*/
void traite_argv (int argc, char *argv[]) {
int option;
/* Verification des parametres */
while ((option = getopt (argc, argv, "hvm:p:u:b:q:")) != -1) {
switch (option) {
case 'h' :
Usage (TRUE);
break;
case 'v' :
Usage (FALSE);
break;
case 'm' :
SET_STRING (serveur, optarg);
break;
case 'p' :
port = atoi (optarg);
break;
case 'u' :
SET_STRING (utilisateur, optarg);
break;
case 'b' :
SET_STRING (boisson, optarg);
break;
case 'q' :
SET_STRING (logout, 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);
}
}
/*
* Envoi de commande
*
*/
int send_cmd (int socket_client) {
char clavier[MAXSTRLEN + 1];
char *commande;
char *admin_crypt;
int i, found = FALSE, cont = TRUE;
/* Lecture d'une commande au clavier */
memset (clavier, 0, MAXSTRLEN);
if ( (fgets (clavier, (int) MAXSTRLEN, stdin) == NULL) &&
feof (stdin) ) {
snprintf (clavier, MAXSTRLEN, "%cquit", cmdchr);
}
/* Determination du type (commande explicite / message) */
if (clavier[0] == cmdchr)
commande = xstrdup (clavier + 1);
else {
commande = xmalloc ((strlen (clavier) + 6) * sizeof (char));
snprintf (commande, strlen (clavier) + 6, "msg %s", clavier);
}
/* Suppression des retours a la ligne pour comparaison */
for (i = 0 ; i < strlen (commande) ; i++)
if (commande[i] == '\n') commande[i] = '\0';
/* Recherche de la bonne commande */
if (strlen (commande) > 0)
for (i = 0 ; i < nb_cmd ; i++) {
int cmp = -1;
if (commandes[i][0] == '*') /* Commandes d'administration */
cmp = strncmp (commandes[i]+1, commande,
strlen (commandes[i])-1);
else if (commandes[i][0] == '+') /* Commandes a intervalle */
cmp = ( (strchr (commandes[i]+1, commande[0]) != NULL) &&
( (strlen (commande) == 1) ||
(commande[1] == ' ') ) ) ? 0 : -1;
else { /* Commande simple : verification pour la commande entiere
* ou le premier caractere.
*/
cmp = (
/* comparaison exacte entre les deux commandes
*/
(strncmp (commandes[i], commande,
strlen (commandes[i]) ) == 0) ||
/* comparaison entre les 2 premieres lettres en
* cas de presence de parametres
*/
( (commandes[i][0] == commande[0]) &&
(commande[1] == ' ') ) ||
/* Comparaison entre les deux premieres lettres en cas
* de presence d'une unique lettre dans la commande
*/
( (commandes[i][0] == commande[0]) &&
(strlen (commande) == 1) ) ) ? 0 : -1;
/* Commande trouvee : si un seul caractere, remplacement par
* la commande complete.
*/
if ( (cmp == 0) &&
(strncmp (commandes[i], commande,
strlen (commandes[i]) ) != 0) ) {
char *tmpstr;
tmpstr = xmalloc ( (strlen (commande) +
strlen (commandes[i]) ) *
sizeof (char) );
strcpy (tmpstr, commandes[i]);
strcat (tmpstr, commande+1);
#ifdef DEBUG
printf ("Nouvelle commande = %s | %d\n",
tmpstr, strlen (tmpstr) );
#endif
if (strlen (tmpstr) > MAXSTRLEN) {
fprintf (stderr, "Commande trop longue !\n");
printf (prompt);
return TRUE; /* continue */
}
free (commande);
commande = xstrdup (tmpstr);
free (tmpstr);
}
#ifdef DEBUG
printf ("l = %c / c = %c ==> %d\n",
commandes[i][0], commande[0], cmp);
#endif
}
if (cmp == 0) {
#ifdef DEBUG
int j;
printf ("Commande reconnue : %s\n[%s (%d)] :",
commandes[i], commande, strlen (commande) );
for (j = 0 ; j < strlen (commande) ; j++)
printf (" %d", commande[j]);
printf ("\n");
#endif
found = TRUE;
}
}
if (! found) {
#ifdef DEBUG
fprintf (stderr, "Commande inconnue : [%s (%d)]",
commande, strlen (commande) );
for (i = 0 ; i < strlen (commande) ; i++)
fprintf (stderr, " %d", commande[i]);
fprintf (stderr, ".\n\n");
#else
fprintf (stderr, "Commande inconnue : [%s]\n", commande);
#endif
printf (prompt);
return TRUE; /* continue */
}
/* Mode administrateur */
if ( (strncmp (commande, "admin ", 6) == 0) && (strlen (commande) > 6) ) {
int taille;
admin_crypt = xstrdup (crypt (commande + 6, "Gs"));
free (commande);
taille = strlen ("admin ") + strlen (admin_crypt) + 1;
commande = xmalloc (taille);
snprintf (commande, taille, "admin %s", admin_crypt + 2);
}
cont = send_infos (socket_client, commande);
free (commande);
return cont;
}
void set_cmds (char *cmds) {
char *tok, *save;
int i = 0;
#ifdef DEBUG
int j;
#endif
nb_cmd = 0;
save = xstrdup (cmds);
#ifdef DEBUG
printf ("Commandes disponibles : \n");
/* printf ("%s\n", cmds); */
#endif
tok = strtok (save, "\n");
while (tok != NULL) {
nb_cmd++;
tok = strtok (NULL, "\n");
}
commandes = xmalloc ((nb_cmd) * sizeof (char*));
tok = strtok (cmds, "\n");
while (tok != NULL) {
commandes[i] = xstrdup (tok);
#ifdef DEBUG
if (tok[0] == '+') {
for (j = 1 ; j < strlen (commandes[i]) ; j++)
printf ("%c%c ", cmdchr, commandes[i][j]);
} else if (tok[0] != '*') {
printf ("%c%s ", cmdchr, commandes[i]);
}
#endif
i++;
tok = strtok (NULL, "\n");
}
printf ("\n");
free (save);
}
/*
* Fonction d'initialisation de la communication
*
*/
int initiate (int socket_client) {
char cmds[MAXSTRLEN];
char datas[MAXSTRLEN];
char nick_ok[MAXSTRLEN];
int cont = TRUE;
memset (datas, 0, MAXSTRLEN);
/* Reception de la liste des commandes */
cont = read_infos (socket_client, cmds);
if (cont) {
set_cmds (cmds);
snprintf (datas, MAXSTRLEN - 1, "%s\n%s\n%s",
utilisateur, boisson, logout);
/* Envoi des donnees utilisateur */
cont = send_infos (socket_client, datas);
read_infos (socket_client, nick_ok);
if (nick_ok[0] == '@') {
printf ("%s", nick_ok + 1);
return FALSE;
}
printf ("%s", nick_ok);
/* Traitement des commandes et des infos */
printf (prompt);
}
return cont;
}
/*
* Boucle de commande et de reception
*
*/
void data_rw (int socket_client) {
int cont = TRUE;
char infos[MAXSTRLEN];
fd_set lire;
cont = initiate (socket_client);
while (cont == TRUE) {
fflush (stdout);
/* Construction de l'ensemble a scruter en lecture : */
FD_ZERO (&lire);
FD_SET (STDIN_FILENO, &lire);
FD_SET (socket_client, &lire);
/* Attente d'un message sur la liste : */
select (socket_client + 1, &lire, NULL, NULL, NULL);
if (FD_ISSET (STDIN_FILENO, &lire) ) {
cont = send_cmd (socket_client);
} else {
int is;
cont = read_infos (socket_client, infos);
is = 0;
do {
printf ("%s\n", infos + is);
while (is < MAXSTRLEN && infos[is]) is ++;
/* on suppose qu'un seul '\0' separe deux messages */
is ++;
} while (is < MAXSTRLEN && infos[is]);
/* Hack pour faire afficher le message par xmessage
* Pas tres joli lors des deconnexions.
*/
/* if (getenv ("DISPLAY")) { */
/* if (! fork ()) */
/* execlp ("xmessage", "xmessage", infos, NULL); */
/* } */
fflush (stdout);
printf (prompt);
}
}
printf ("%s\n", logout);
close (socket_client);
}
/*
* Gestionnaire de signal SIGPIPE
*
*/
void handler_sigpipe (int sig) {
printf ("Signal SIGPIPE recu...\n");
}
/*
* Fonction principale
*
*/
int main (int argc, char *argv[]) {
int socket_client;
char *environ_user;
signal (SIGPIPE, handler_sigpipe);
/* Verification des parametres */
traite_argv (argc, argv);
/* Lecture du fichier de config */
load_config ();
/* Valeurs par defaut */
if (! utilisateur) {
environ_user = getenv ("USER");
if (environ_user && *environ_user)
utilisateur = xstrdup (environ_user);
else
utilisateur = xstrdup ("toto");
}
if (IS_NOT_GOOD (serveur)) SET_STRING (serveur, DEFAULT_SERVER);
if (IS_NOT_GOOD (prompt)) SET_STRING (prompt, DEFAULT_PROMPT);
if (IS_NOT_GOOD (boisson)) SET_STRING (boisson, DEFAULT_DRINK);
if (IS_NOT_GOOD (logout)) SET_STRING (logout, DEFAULT_LOGOUT);
if (cmdchr == 0) cmdchr = '/';
if (port == 0) port = DEFAULT_SERVER_PORT;
printf ("Serveur : [%s]\t", serveur);
printf ("Port : [%d]\n", port);
printf ("Utilisateur : [%s]\t", utilisateur);
printf ("\tBoisson : [%s]\t", boisson);
printf ("Logout : [%s]\n", logout);
printf ("Prefixe : [%c]\n", cmdchr);
/* Connexion au serveur */
if ( (socket_client = connect_server (serveur, port) ) == -1) {
fprintf (stderr, "Connexion refusee...\n");
return -1;
}
printf ("-+- Connexion acceptee. -+-\n");
data_rw (socket_client);
libere ();
return 0;
}

17
guinness.h Normal file
View File

@@ -0,0 +1,17 @@
/*
* guinness
* architecture clients/serveur guinness.
* Thomas Nemeth -- le 15 juin 2001
*
*/
#ifndef GUINNESS_CLIENT
#define GUINNESS_CLIENT
#define CONFIG_FILE ".guinnessrc"
#define DEFAULT_SERVER "127.0.0.1"
#define DEFAULT_PROMPT "> "
#endif

View File

@@ -32,6 +32,8 @@
#include "commands.h"
#include "config.h"
pthread_mutex_t mutex_clients;
/* Config specifique serveur */
char *adr_ip = NULL;
int port = 0;
@@ -68,23 +70,23 @@ void install_handler ();
void handler_signaux (int sig) {
switch (sig) {
case SIGPIPE:
printlog (LOG_NOTIFY, "Signal SIGPIPE reçu...\n");
printlog (LOG_NOTIFY, "Signal SIGPIPE recu...\n");
install_handler ();
break;
case SIGTERM:
case SIGQUIT:
case SIGINT:
online = FALSE;
printlog (LOG_NOTIFY, "Signal de terminaison reçu...\n");
printlog (LOG_NOTIFY, "Signal de terminaison recu...\n");
break;
default:
printlog (LOG_NOTIFY, "Signal reçu...\n");
printlog (LOG_NOTIFY, "Signal recu...\n");
}
}
/*
* Lecture du fichier de config : récupération des valeurs
* Lecture du fichier de config : recuperation des valeurs
*
*/
char *get_string_from_token (char *line) {
@@ -154,13 +156,13 @@ void Usage (int help) {
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"
" -h : aide sur les parametres\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"
" -b : detache le serveur du terminal\n"
" -a adresse : specifie l'adresse du serveur\n"
" -p port : specifie le numero du port\n"
" -s passwd : specifie le mot de passe d'aministration\n"
" -d chemin : indique le chemin ou se"
" trouvent les ascii-arts\n"
" -l fichier : fichier de log\n"
" -f fichier : fichier de configuration\n\n");
@@ -176,7 +178,7 @@ int traite_argv (int argc, char *argv[]) {
int option;
int detach = FALSE;
/* Vérification des paramètres */
/* Verification des parametres */
while ((option = getopt (argc, argv, "hvba:p:s:d:l:f:")) != -1) {
switch (option) {
case 'h' :
@@ -260,7 +262,7 @@ int initiate (int socket_service, userinfos *infos) {
memset (userdatas, 0, MAXSTRLEN);
/* Récupération des infos sur le connecté */
/* Recuperation des infos sur le connecte */
get_sock_infos (socket_service,
&nom_distant, &ip_distant,
&port_local, &port_distant);
@@ -284,18 +286,18 @@ int initiate (int socket_service, userinfos *infos) {
if ( (cont = send_servercmds (socket_service)) == FALSE)
return cont;
/* 2. attente des données du connecté */
/* 2. attente des donnees du connecte */
if ( (cont = read_infos (socket_service, userdatas)) == FALSE)
return cont;
/* FIN DU PROTOCOLE : Véricifations / ajout dans la liste / affichage */
/* FIN DU PROTOCOLE : Vericifations / 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 */
/* Boisson preferee */
token = strtok_r (NULL, delim, &saveptr);
snprintf (infos->prefb, MAXSTRLEN, "%s", token ? token : drink);
@@ -309,7 +311,7 @@ int initiate (int socket_service, userinfos *infos) {
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, "Boisson preferee : [%s]\n", infos->prefb);
printlog (LOG_NOTIFY, "Message de logout : [%s]\n", infos->logout);
printlog (LOG_NOTIFY, "Date de connexion : [%s]\n", infos->cxdate);
@@ -318,8 +320,8 @@ int initiate (int socket_service, userinfos *infos) {
char nick_ok[MAXSTRLEN+1];
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);
send_infos (socket_service, "@Pseudo deja utilise !\n");
printlog (LOG_NOTIFY, "Pseudo deje utilise => %s\n", infos->nom);
pthread_mutex_unlock (&mutex_clients);
return FALSE;
}
@@ -329,8 +331,8 @@ int initiate (int socket_service, userinfos *infos) {
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");
"Votre boisson preferee n'est pas disponible sur ce"
" serveur !\nVous aurez des Guinness a la place.\n");
/* Passage en mode non bloquant */
fcntl (socket_service, F_SETFL, O_NONBLOCK);
@@ -369,13 +371,13 @@ void thread_service (int *sock_serv) {
}
#ifdef DEBUG
printlog (LOG_NOTIFY, "Prêt à recevoir des commandes.\n");
printlog (LOG_NOTIFY, "Pret a recevoir des commandes.\n");
#endif
while (cont == TRUE) {
memset (commande, 0, MAXSTRLEN + 1);
/* Lecture des caractères reçus */
/* Lecture des caracteres recus */
do {
sleep (1);
nb = read (socket_service, commande, MAXSTRLEN);
@@ -384,7 +386,7 @@ void thread_service (int *sock_serv) {
if ( (errno == EPIPE) || (nb == 0) ) {
cont = FALSE;
} else {
printlog (LOG_ERROR, "Erreur de connexion réception !\n");
printlog (LOG_ERROR, "Erreur de connexion reception !\n");
}
}
} while ( (cont != FALSE) &&
@@ -392,7 +394,7 @@ void thread_service (int *sock_serv) {
(new_message (old_id) != TRUE) );
#ifdef DEBUG
printlog (LOG_NOTIFY, "Commande reçue.\n");
printlog (LOG_NOTIFY, "Commande recue.\n");
#endif
if (cont == TRUE) {
/* Traitement de la commande */
@@ -403,7 +405,7 @@ void thread_service (int *sock_serv) {
old_id = get_broadcastid ();
cont = send_broadcast (socket_service, &infos);
#ifdef DEBUG
printlog (LOG_ERROR, "Émission broadcast pour %s (id = %ld)\n",
printlog (LOG_ERROR, "Emission broadcast pour %s (id = %ld)\n",
infos.nom, old_id);
#endif
}
@@ -436,20 +438,30 @@ void install_handler () {
/*
* Initialisation générale
* Initialisation generale
*
*/
void guinnessd_init (int argc, char *argv[]) {
pthread_mutexattr_t mutex_attr;
char *cptr;
setlocale (LC_ALL, "");
install_handler ();
/* Valeurs par défaut */
/* Valeurs par defaut */
logfile = stdout;
outerr = stderr;
/* Traitement des paramètres */
/* est-ce bien la place pour initialiser des trucs avant le parsing de
la ligne de commande ? Eg: la variable d'environnement DRINKS_DIR
*/
if (NULL!=(cptr=getenv("DRINKS_DIR"))) {
chemin = xstrdup(cptr);
}
/* Traitement des parametres */
if (traite_argv (argc, argv) == TRUE) {
switch (fork()) {
case -1: /* erreur */
@@ -458,7 +470,7 @@ void guinnessd_init (int argc, char *argv[]) {
case 0: /* le fils */
setsid ();
break;
default: /* le père */
default: /* le pere */
exit (0);
}
}
@@ -466,12 +478,12 @@ void guinnessd_init (int argc, char *argv[]) {
/* Lecture du fichier de configuration */
load_config ();
/* Initialisation des sémaphores */
/* Initialisation des semaphores */
pthread_mutexattr_init (&mutex_attr);
pthread_mutex_init (&mutex_broadcast, &mutex_attr);
pthread_mutex_init (&mutex_clients, &mutex_attr);
/* Affectation des paramètres */
/* Affectation des parametres */
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);
@@ -488,7 +500,7 @@ void guinnessd_init (int argc, char *argv[]) {
/* Option pour le buffer de logs */
setvbuf (logfile, NULL, _IOLBF, 0);
/* Création de la liste de boissons par défaut*/
/* Creation de la liste de boissons par defaut*/
add_elt (&drinks_list, "guinness");
if (! chemin) chemin = xstrdup (DRINKS_DIR);
@@ -510,7 +522,7 @@ int main (int argc, char *argv[]) {
guinnessd_init (argc, argv);
/* Installation de l'écoute du serveur */
/* Installation de l'ecoute du serveur */
if ( (socket_ecoute = install_server (port, adr_ip, NULL)) == -1) {
printlog (LOG_ERROR, "Impossible d'installer le service.\n");
return -1;
@@ -548,21 +560,21 @@ int main (int argc, char *argv[]) {
return -1;
}
/* Ici connexion acceptée */
printlog (LOG_NOTIFY, "Connexion acceptée...\n");
/* Ici connexion acceptee */
printlog (LOG_NOTIFY, "Connexion acceptee...\n");
/* Lancement d'une activité de traitement */
/* Lancement d'une activite 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");
printlog (LOG_ERROR, "Erreur creation thread de service.\n");
close (socket_service);
}
/* fflush (logfile); */
sleep (2);
}
printlog (LOG_NOTIFY, "Arrêt du serveur demandé.\n");
printlog (LOG_NOTIFY, "Arret du serveur demande.\n");
/* fflush (logfile); */
close (socket_ecoute);

View File

@@ -26,12 +26,12 @@ typedef struct userinfos {
int port;
int admin;
int cold;
int comm[2]; /* Pas encore utilisé */
int comm[2]; /* Pas encore utilise */
} userinfos;
pthread_mutex_t mutex_broadcast;
pthread_mutex_t mutex_clients;
extern pthread_mutex_t mutex_broadcast;
extern pthread_mutex_t mutex_clients;
#endif

23
picoles/canabis Normal file
View File

@@ -0,0 +1,23 @@
.:.
:|:
.:|:.
::|::
:. ::|:: .:
:|:. .::|::. .:|:
::|:. :::|::: .:|:;
`::|:. :::|::: .:|::'
::|::. :::|::: .::|:;
`::|::. :::|::: .::|::'
:::|::. :::|::: .::|::;
`:::|::. :::|::: .::|::;'
`::. `:::|::. :::|::: .::|::;' .:;'
`:::.. `:::|::. :::|::: .::|::;' ..::;'
`::::::. `:::|::. :::|::: .::|::;' .:::::;'
`::::::.`:::|::.:::|::;.::|::;'.:::::;'
`::::::.`::|::.::|::.::|::'.:::::;'
`:::::::::|:::|:::|::::::::;'
``:::::::|:|::|:::::;''
`::::::::::;'
.:;'' ::: ``::.
: : :
':`

25
picoles/champagne Normal file
View File

@@ -0,0 +1,25 @@
o oo" " "
o o o"" "o
o" M "
"o " o M ""
M "o" MoMo
"" o o"oo
M"o "o" M
oMoo" Mo"
M"o "M MM
"o"o"o M
"oM"oMMo
M "M M
"M"oM"
M o
o o
o
" o
Mo
o
"o
"o
MMo
oM"o o
oo M"ooM"MoMoo
" " "

18
picoles/pastis Normal file
View File

@@ -0,0 +1,18 @@
+----------------+
|__ _____ |
|/~|~~|~~~/~|~~~~|
| \| | /\ | |
|-555555---- 1 |
| 55 111 |
| 55 1 11 |
| 5555 11 |
| 555 11 |
| 55 11 |
| 55 11 |
| 555555 111111 |
| |
| Le Pastis |
| |
|================|
| |
+----------------+

22
picoles/steinlager Normal file
View File

@@ -0,0 +1,22 @@
.sssssssss.
.sssssssssssssssssss
sssssssssssssssssssssssss
ssssssssssssssssssssssssssss
@@sssssssssssssssssssssss@ss
|s@@@@sssssssssssssss@@@@s|s
_______|sssss@@@@@sssss@@@@@sssss|s
/ sssssssss@sssss@sssssssss|s
/ .------+.ssssssss@sssss@ssssssss.|
/ / |...sssssss@sss@sssssss...|
| | |.......sss@sss@ssss......|
| | |..........s@ss@sss.......|
| | |...........@ss@..........|
\ \ |............ss@..........|
\ '------+...........ss@...........|
\________ .........................|
|.........................|
/...........................\
|.............................|
|.......................|
|...............|

View File

@@ -1,7 +1,7 @@
/*
* printlog
* architecture clients/serveur guinness
* Thomas Nemeth / Arnaud Giersch -- le 23 août 2001
* Thomas Nemeth / Arnaud Giersch -- le 23 aout 2001
*
*/

View File

@@ -1,7 +1,7 @@
/*
* printlog
* architecture clients/serveur guinness
* Thomas Nemeth / Arnaud Giersch -- le 23 août 2001
* Thomas Nemeth / Arnaud Giersch -- le 23 aout 2001
*
*/

48
tools.c
View File

@@ -1,6 +1,6 @@
/*
* tools
* Création et manipulation de sockets
* Creation et manipulation de sockets
* Thomas Nemeth -- le 15 juin 2001
*
*/
@@ -22,9 +22,9 @@
#include "tools.h"
/*
* Ouverture d'une socket de type flot de données
* Ouverture d'une socket de type flot de donnees
*
* création d'une socket serveur : port != 0
* creation d'une socket serveur : port != 0
*
*/
int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
@@ -35,7 +35,7 @@ int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
struct linger ling;
/*
* Création de la socket
* Creation de la socket
*
*/
if ( (desc_soc = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
@@ -72,7 +72,7 @@ int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
}
/*
* Préparation de l'adresse d'attachement
* Preparation de l'adresse d'attachement
*
*/
memset (&adresse, 0, sizeof (adresse) );
@@ -103,7 +103,7 @@ int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
if (bind (desc_soc, (struct sockaddr*) &adresse, lg_adresse) == -1) {
#ifdef DEBUG
fprintf (stderr,
"Ne peut donner de nom à la socket de connexion.\n"
"Ne peut donner de nom a la socket de connexion.\n"
"Attendez quelques minutes avant de relancer.\n");
#endif
perror (__FILE__ " bind");
@@ -112,7 +112,7 @@ int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
}
/*
* Récupération de l'adresse effective d'attachement
* Recuperation de l'adresse effective d'attachement
*
*/
if (ptr_adresse != NULL)
@@ -127,7 +127,7 @@ int connect_server (const char *machine, int port) {
struct sockaddr_in adresse_serveur, adresse_client;
int socket_client;
/* Recherche de la machine où se trouve le serveur */
/* Recherche de la machine ou se trouve le serveur */
if ( (serveur = gethostbyname (machine) ) == NULL) {
#ifdef DEBUG
fprintf (stderr, "Machine %s inconnue...\n", machine);
@@ -135,18 +135,18 @@ int connect_server (const char *machine, int port) {
return -1;
}
/* Création et attachement de la socket du client --
/* Creation 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");
fprintf (stderr, "Creation de la socket du client impossible.\n");
#endif
return -1;
}
/* Préparation de l'adresse du serveur */
/* Preparation de l'adresse du serveur */
adresse_serveur.sin_family = AF_INET;
adresse_serveur.sin_port = htons (port);
memcpy (&adresse_serveur.sin_addr.s_addr,
@@ -172,12 +172,12 @@ int install_server (int port, char *adr_ip, struct sockaddr_in *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");
fprintf (stderr, "Creation de la socket du serveur impossible.\n");
#endif
return -1;
}
/* Déclaration d'ouverture du service */
/* Declaration d'ouverture du service */
if (listen (socket_ecoute, 10) == -1) {
#ifdef DEBUG
fprintf (stderr, "Impossible d'enregistrer le service.\n");
@@ -191,7 +191,7 @@ int install_server (int port, char *adr_ip, struct sockaddr_in *ecoute) {
/*
* Fonction de réception de données
* Fonction de reception de donnees
*
*/
int read_infos (int socket_data, char *infos) {
@@ -203,13 +203,13 @@ int read_infos (int socket_data, char *infos) {
if ( (nb == -1) || (nb == 0) ) {
#ifdef DEBUG
fprintf (stderr, "Erreur de connexion réception !\n");
fprintf (stderr, "Erreur de connexion reception !\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);
printf ("Recu : [%s] lg = %d/%d\n", infos, strlen (infos), nb);
#endif
return TRUE;
@@ -217,24 +217,24 @@ int read_infos (int socket_data, char *infos) {
/*
* Fonction d'émisson de données
* Fonction d'emisson de donnees
*
*/
int send_infos (int socket_data, const char *infos) {
#ifdef DEBUG
printf ("Émission de : %s [%d]\n", infos, strlen (infos));
printf ("Emission 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");
fprintf (stderr, "Erreur de connexion emission !\n");
#endif
if (errno == EPIPE) return FALSE; /*cont = FALSE;*/
}
#ifdef DEBUG
fprintf (stderr, "Émission ok !\n");
fprintf (stderr, "Emission ok !\n");
#endif
return TRUE;
}
@@ -249,7 +249,7 @@ void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
#endif
struct hostent *machine;
/* Initialisations en cas d'échecs */
/* Initialisations en cas d'echecs */
*nom = NULL;
*adr = NULL;
*prd = 0;
@@ -267,7 +267,7 @@ void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
namelen = sizeof (name);
if (getpeername (sock, (struct sockaddr *) &name, &namelen) != 0) {
#ifdef DEBUG
perror ("Erreur de récupération d'information sur pair !\n"
perror ("Erreur de recuperation d'information sur pair !\n"
"getpeername() ");
#else
perror ("Impossible d'obtenir les infos distantes ");
@@ -283,12 +283,12 @@ void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
sizeof name.sin_addr, name.sin_family);
if (machine == NULL) {
#ifdef DEBUG
perror ("Erreur de récupération de nom de pair.\n"
perror ("Erreur de recuperation 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 ");
perror ("Impossible d'obtenir le nom d'hote distant ");
#endif
return;
}

View File

@@ -1,6 +1,6 @@
/*
* tools
* Création et manipulation de sockets
* Creation et manipulation de sockets
* Thomas Nemeth -- le 15 juin 2001
*
*/

4
xmem.c
View File

@@ -1,7 +1,7 @@
/*
* xmem
* architecture clients/serveur guinness : gestion mémoire
* Thomas Nemeth -- le 24 août 2001
* architecture clients/serveur guinness : gestion memoire
* Thomas Nemeth -- le 24 aout 2001
*
*/

4
xmem.h
View File

@@ -1,7 +1,7 @@
/*
* xmem
* architecture clients/serveur guinness : gestion mémoire
* Thomas Nemeth -- le 24 août 2001
* architecture clients/serveur guinness : gestion memoire
* Thomas Nemeth -- le 24 aout 2001
*
*/