275 lignes
6.7 KiB
C
275 lignes
6.7 KiB
C
/*
|
||
* 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<EFBFBD>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<EFBFBD>u : ID = %s\n", token);
|
||
#endif
|
||
|
||
/* type */
|
||
token = strtok_r (NULL, SEP, &saveptr);
|
||
#ifdef DEBUG
|
||
printf ("Re<EFBFBD>u : TYPE = %s\n", token);
|
||
#endif
|
||
*t = atoi (token);
|
||
|
||
/* from */
|
||
token = strtok_r (NULL, SEP, &saveptr);
|
||
#ifdef DEBUG
|
||
printf ("Re<EFBFBD>u : FROM = %s\n", token);
|
||
#endif
|
||
*f = NULL;
|
||
if (token) *f = xstrdup (token);
|
||
|
||
/* message */
|
||
token = strtok_r (NULL, SEP, &saveptr);
|
||
#ifdef DEBUG
|
||
printf ("Re<EFBFBD>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 <20>l<EFBFBD>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<EFBFBD>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<EFBFBD>connexion de [%s] : %s",
|
||
from, mesg);
|
||
break;
|
||
case TOURNEE: /* Tourn<72>e g<>n<EFBFBD>rale */
|
||
if (mesg == NULL) {
|
||
snprintf (head, MAXSTRLEN - 1,
|
||
" -+- Tourn<72>e g<>n<EFBFBD>rale offerte par %s ! -+-",
|
||
from);
|
||
breuv = drinks_get (infos->prefb);
|
||
} else {
|
||
snprintf (head, MAXSTRLEN - 1,
|
||
" -+- Tourn<72>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<72>.\n");
|
||
type = -1;
|
||
}
|
||
|
||
if (from) free (from);
|
||
if (mesg) free (mesg);
|
||
|
||
if (type != -1) cont = send_infos (socket_service, datas);
|
||
|
||
return cont;
|
||
}
|