Comment servir des pintes de Guinness "over Internet" ;) Reprise/Fork d'un très ancien code d'un pilier de f.m.b.l : http://tnemeth.free.fr/projets/guinness-server.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

broadcast.c 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * guinnessd
  3. * architecture clients/serveur guinness : broadcast messages
  4. * Thomas Nemeth -- le 15 juin 2001
  5. *
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <pthread.h>
  13. #include <fcntl.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <string.h>
  18. #include <strings.h>
  19. #include "defines.h"
  20. #include "printlog.h"
  21. #include "xmem.h"
  22. #include "guinnessd.h"
  23. #include "lists.h"
  24. #include "tools.h"
  25. #include "broadcast.h"
  26. #include "drinks.h"
  27. extern Elt *clients_list;
  28. extern FILE *outerr;
  29. static int count = 0;
  30. static unsigned long id = 0;
  31. static Elt *bdcast_list = NULL;
  32. unsigned long get_first_id () {
  33. unsigned long ret = id;
  34. if (bdcast_list) {
  35. char *first_msg;
  36. first_msg = elt_number (bdcast_list, 0);
  37. ret = strtoul (first_msg, (char **)NULL, 10);
  38. }
  39. return ret;
  40. }
  41. unsigned long get_last_id () {
  42. unsigned long ret = id;
  43. if (bdcast_list) {
  44. char *last_msg;
  45. last_msg = elt_number (bdcast_list, get_nb_elts (bdcast_list) - 1);
  46. ret = strtoul (last_msg, (char **)NULL, 10);
  47. }
  48. return ret;
  49. }
  50. void next_broadcast (int new) {
  51. #ifdef DEBUG
  52. printlog (LOG_NOTIFY, "Suivant ? (%ld restants / %s)\n",
  53. get_nb_elts (bdcast_list), new ? "NEW" : "SUITE");
  54. #endif
  55. if ( (new && (get_nb_elts (bdcast_list) == 1) ) ||
  56. ( (!new) && (get_nb_elts (bdcast_list) >= 1) ) ) {
  57. pthread_mutex_lock (&mutex_clients);
  58. count = get_nb_elts (clients_list);
  59. pthread_mutex_unlock (&mutex_clients);
  60. id = get_last_id ();
  61. #ifdef DEBUG
  62. printlog (LOG_NOTIFY, "Message en lisse (id = %ld / count = %d)...\n",
  63. id, count);
  64. #endif
  65. }
  66. }
  67. int broadcast (int t, const char *f, const char *m) {
  68. int taille;
  69. char sid[MAXSTRLEN];
  70. char stype[MAXSTRLEN];
  71. char *message;
  72. pthread_mutex_lock (&mutex_clients);
  73. if (get_nb_elts (clients_list) == 0) {
  74. pthread_mutex_unlock (&mutex_clients);
  75. return TRUE;
  76. }
  77. pthread_mutex_unlock (&mutex_clients);
  78. pthread_mutex_lock (&mutex_broadcast);
  79. memset (sid, 0, MAXSTRLEN);
  80. memset (stype, 0, MAXSTRLEN);
  81. snprintf (sid, MAXSTRLEN - 1, "%ld", get_last_id () + 1);
  82. snprintf (stype, MAXSTRLEN - 1, "%d", t);
  83. taille = (strlen (sid) +
  84. strlen (stype) +
  85. (f ? strlen (f) : 3) +
  86. (m ? strlen (m) : 0) +
  87. 5) * sizeof (char);
  88. message = xmalloc (taille);
  89. memset (message, 0, taille);
  90. /* i_| t_| f_| m_ */
  91. snprintf (message, taille, "%s%s%s%s%s%s%s",
  92. sid, SEP,
  93. stype, SEP,
  94. f ? f : "---", SEP,
  95. m ? m : "");
  96. add_elt (&bdcast_list, message);
  97. free (message);
  98. next_broadcast (TRUE);
  99. #ifdef DEBUG
  100. printlog (LOG_NOTIFY,
  101. "Broadcast id = %s\t"
  102. "type = %s\t"
  103. "de = %s\n",
  104. sid,
  105. t == 1 ? "QUITTER" :
  106. t == 2 ? "TOURNEE" :
  107. t == 3 ? "MESSAGE" : "RIEN",
  108. f);
  109. #endif
  110. pthread_mutex_unlock (&mutex_broadcast);
  111. return TRUE;
  112. }
  113. int new_message (long cid) {
  114. int res;
  115. pthread_mutex_lock (&mutex_broadcast);
  116. res = (id > cid);
  117. pthread_mutex_unlock (&mutex_broadcast);
  118. return res;
  119. }
  120. int get_broadcastid () {
  121. int res;
  122. pthread_mutex_lock (&mutex_broadcast);
  123. res = id;
  124. pthread_mutex_unlock (&mutex_broadcast);
  125. return res;
  126. }
  127. void get_broadcastmsg (int *t, char **f, char **m) {
  128. char *token, *bdcast, *saveptr;
  129. pthread_mutex_lock (&mutex_broadcast);
  130. bdcast = xstrdup (elt_number (bdcast_list, 0));
  131. pthread_mutex_unlock (&mutex_broadcast);
  132. if (bdcast) {
  133. #ifdef DEBUG
  134. printf ("Broadcast tokenisation : %s\n", bdcast);
  135. #endif
  136. /* id */
  137. token = strtok_r (bdcast, SEP, &saveptr);
  138. #ifdef DEBUG
  139. printf ("Recu : ID = %s\n", token);
  140. #endif
  141. /* type */
  142. token = strtok_r (NULL, SEP, &saveptr);
  143. #ifdef DEBUG
  144. printf ("Recu : TYPE = %s\n", token);
  145. #endif
  146. *t = atoi (token);
  147. /* from */
  148. token = strtok_r (NULL, SEP, &saveptr);
  149. #ifdef DEBUG
  150. printf ("Recu : FROM = %s\n", token);
  151. #endif
  152. *f = NULL;
  153. if (token) *f = xstrdup (token);
  154. /* message */
  155. token = strtok_r (NULL, SEP, &saveptr);
  156. #ifdef DEBUG
  157. printf ("Recu : MESSAGE = %s\n", token);
  158. #endif
  159. *m = NULL;
  160. if (token) *m = xstrdup (token);
  161. pthread_mutex_lock (&mutex_broadcast);
  162. if (count > 0) count--;
  163. #ifdef DEBUG
  164. printf ("count = %d\n", count);
  165. #endif
  166. if (count == 0) {
  167. remove_elt_n (&bdcast_list, 0);
  168. #ifdef DEBUG
  169. printf ("Suppression du premier element. Liste = %s\n",
  170. bdcast_list ? "OK." : "NULL !");
  171. #endif
  172. next_broadcast (FALSE);
  173. }
  174. pthread_mutex_unlock (&mutex_broadcast);
  175. }
  176. }
  177. int send_broadcast (int socket_service, userinfos *infos) {
  178. char datas[MAXSTRLEN];
  179. char head[MAXSTRLEN];
  180. char *from = NULL, *mesg = NULL, *breuv = NULL;
  181. int type, cont = TRUE;
  182. memset (datas, 0, MAXSTRLEN);
  183. get_broadcastmsg (&type, &from, &mesg);
  184. printlog (LOG_NOTIFY, "Broadcast pour [%s] : %s\n",
  185. infos->nom,
  186. type == 1 ? "QUITTER" :
  187. type == 2 ? "TOURNEE" :
  188. type == 3 ? "MESSAGE" :
  189. "ERREUR");
  190. printlog (LOG_NOTIFY, " de [%s] : %s\n", from, mesg ? mesg : "RIEN");
  191. switch (type) {
  192. case QUITTER: /* Un utilisateur se deconnecte */
  193. snprintf (datas, MAXSTRLEN - 1, "Deconnexion de [%s] : %s",
  194. from, mesg);
  195. break;
  196. case TOURNEE: /* Tournee generale */
  197. if (mesg == NULL) {
  198. snprintf (head, MAXSTRLEN - 1,
  199. " -+- Tournee generale offerte par %s ! -+-",
  200. from);
  201. breuv = drinks_get (infos->prefb);
  202. } else {
  203. snprintf (head, MAXSTRLEN - 1,
  204. " -+- Tournee de %s offerte par %s ! -+-",
  205. mesg, from);
  206. breuv = drinks_get (mesg);
  207. }
  208. snprintf (datas, MAXSTRLEN - 1, "%s\n%s%s\n", head, breuv, head);
  209. free (breuv);
  210. break;
  211. case MESSAGE: /* Message */
  212. snprintf (datas, MAXSTRLEN - 1, "<%s> %s\n", from, mesg);
  213. break;
  214. default:
  215. printlog (LOG_ERROR, "Type de message broadcast non supporte.\n");
  216. type = -1;
  217. }
  218. if (from) free (from);
  219. if (mesg) free (mesg);
  220. if (type != -1) cont = send_infos (socket_service, datas);
  221. return cont;
  222. }