sad

simple audio daemon
git clone git://git.2f30.org/sad
Log | Files | Refs | LICENSE

notify.c (1944B)


      1 #include <sys/select.h>
      2 
      3 #include <err.h>
      4 #include <limits.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "queue.h"
     10 #include "sad.h"
     11 
     12 Eventdesc Eventmap[] = {
     13     {EVSONGFINISHED, "songfinished"},
     14 };
     15 
     16 struct subscriber {
     17   int clifd;
     18   int event;
     19   TAILQ_ENTRY(subscriber) entry;
     20 };
     21 
     22 static TAILQ_HEAD(subscribers, subscriber) subscribers;
     23 
     24 int initnotifier(void) {
     25   TAILQ_INIT(&subscribers);
     26   return 0;
     27 }
     28 
     29 int addsubscriber(int clifd, int event) {
     30   struct subscriber *s;
     31   size_t i;
     32 
     33   for (i = 0; i < LEN(Eventmap); i++)
     34     if (Eventmap[i].event == event)
     35       break;
     36   if (i == LEN(Eventmap))
     37     return -1;
     38 
     39   TAILQ_FOREACH(s, &subscribers, entry)
     40   if (s->clifd == clifd && s->event == event)
     41     return 0; /* do not queue events */
     42 
     43   s = malloc(sizeof(*s));
     44   if (!s)
     45     err(1, "malloc");
     46 
     47   s->clifd = clifd;
     48   s->event = event;
     49   TAILQ_INSERT_TAIL(&subscribers, s, entry);
     50 
     51   return 0;
     52 }
     53 
     54 int addsubscribername(int clifd, const char *name) {
     55   size_t i;
     56 
     57   for (i = 0; i < LEN(Eventmap); i++)
     58     if (!strcmp(Eventmap[i].name, name))
     59       return addsubscriber(clifd, Eventmap[i].event);
     60   return -1;
     61 }
     62 
     63 int notify(int event) {
     64   struct subscriber *s, *tmp;
     65   size_t i;
     66 
     67   for (i = 0; i < LEN(Eventmap); i++)
     68     if (Eventmap[i].event == event)
     69       break;
     70   if (i == LEN(Eventmap))
     71     return -1;
     72 
     73   TAILQ_FOREACH_SAFE(s, &subscribers, entry, tmp) {
     74     if (s->event != event)
     75       continue;
     76     for (i = 0; i < LEN(Eventmap); i++) {
     77       if (Eventmap[i].event == s->event) {
     78         dprintf(s->clifd, "event: %s\n", Eventmap[i].name);
     79         dprintf(s->clifd, "OK\n");
     80         TAILQ_REMOVE(&subscribers, s, entry);
     81         free(s);
     82         break;
     83       }
     84     }
     85   }
     86   return 0;
     87 }
     88 
     89 void removesubscriber(int clifd) {
     90   struct subscriber *s, *tmp;
     91 
     92   TAILQ_FOREACH_SAFE(s, &subscribers, entry, tmp) {
     93     if (s->clifd == clifd) {
     94       TAILQ_REMOVE(&subscribers, s, entry);
     95       free(s);
     96     }
     97   }
     98 }