123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /*
- * 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;
- }
|