server is running, expect more bugs
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user