2020-03-28 10:59:41 +01:00
|
|
|
/*
|
|
|
|
* 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" :
|
2020-04-14 23:41:07 +02:00
|
|
|
t == 2 ? "TOURNEE" :
|
2020-03-28 10:59:41 +01:00
|
|
|
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
|
2020-04-14 23:41:07 +02:00
|
|
|
printf ("Recu : ID = %s\n", token);
|
2020-03-28 10:59:41 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* type */
|
|
|
|
token = strtok_r (NULL, SEP, &saveptr);
|
|
|
|
#ifdef DEBUG
|
2020-04-14 23:41:07 +02:00
|
|
|
printf ("Recu : TYPE = %s\n", token);
|
2020-03-28 10:59:41 +01:00
|
|
|
#endif
|
|
|
|
*t = atoi (token);
|
|
|
|
|
|
|
|
/* from */
|
|
|
|
token = strtok_r (NULL, SEP, &saveptr);
|
|
|
|
#ifdef DEBUG
|
2020-04-14 23:41:07 +02:00
|
|
|
printf ("Recu : FROM = %s\n", token);
|
2020-03-28 10:59:41 +01:00
|
|
|
#endif
|
|
|
|
*f = NULL;
|
|
|
|
if (token) *f = xstrdup (token);
|
|
|
|
|
|
|
|
/* message */
|
|
|
|
token = strtok_r (NULL, SEP, &saveptr);
|
|
|
|
#ifdef DEBUG
|
2020-04-14 23:41:07 +02:00
|
|
|
printf ("Recu : MESSAGE = %s\n", token);
|
2020-03-28 10:59:41 +01:00
|
|
|
#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
|
2020-04-14 23:41:07 +02:00
|
|
|
printf ("Suppression du premier element. Liste = %s\n",
|
2020-03-28 10:59:41 +01:00
|
|
|
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" :
|
2020-04-14 23:41:07 +02:00
|
|
|
type == 2 ? "TOURNEE" :
|
2020-03-28 10:59:41 +01:00
|
|
|
type == 3 ? "MESSAGE" :
|
|
|
|
"ERREUR");
|
|
|
|
printlog (LOG_NOTIFY, " de [%s] : %s\n", from, mesg ? mesg : "RIEN");
|
|
|
|
|
|
|
|
switch (type) {
|
2020-04-14 23:41:07 +02:00
|
|
|
case QUITTER: /* Un utilisateur se deconnecte */
|
|
|
|
snprintf (datas, MAXSTRLEN - 1, "Deconnexion de [%s] : %s",
|
2020-03-28 10:59:41 +01:00
|
|
|
from, mesg);
|
|
|
|
break;
|
2020-04-14 23:41:07 +02:00
|
|
|
case TOURNEE: /* Tournee generale */
|
2020-03-28 10:59:41 +01:00
|
|
|
if (mesg == NULL) {
|
|
|
|
snprintf (head, MAXSTRLEN - 1,
|
2020-04-14 23:41:07 +02:00
|
|
|
" -+- Tournee generale offerte par %s ! -+-",
|
2020-03-28 10:59:41 +01:00
|
|
|
from);
|
|
|
|
breuv = drinks_get (infos->prefb);
|
|
|
|
} else {
|
|
|
|
snprintf (head, MAXSTRLEN - 1,
|
2020-04-14 23:41:07 +02:00
|
|
|
" -+- Tournee de %s offerte par %s ! -+-",
|
2020-03-28 10:59:41 +01:00
|
|
|
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:
|
2020-04-14 23:41:07 +02:00
|
|
|
printlog (LOG_ERROR, "Type de message broadcast non supporte.\n");
|
2020-03-28 10:59:41 +01:00
|
|
|
type = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (from) free (from);
|
|
|
|
if (mesg) free (mesg);
|
|
|
|
|
|
|
|
if (type != -1) cont = send_infos (socket_service, datas);
|
|
|
|
|
|
|
|
return cont;
|
|
|
|
}
|