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 }