7 #include <sys/socket.h>
8 #include <netinet/in.h>
10 #include <arpa/inet.h>
13 #include <libnotify/notify.h>
16 #define QUEUE_LENGTH 10
18 // a function to reap future child processes
19 void sigchld_handler(int s
)
21 while(waitpid(-1, NULL
, WNOHANG
) > 0);
24 // look for an IPv4/6 host:port in an address structure
25 void *get_in_addr(struct sockaddr
*sa
)
27 if (sa
->sa_family
== AF_INET
) {
28 return &(((struct sockaddr_in
*)sa
)->sin_addr
);
30 return &(((struct sockaddr_in6
*)sa
)->sin6_addr
);
35 // new connections on activefd, always listening on sockfd
37 struct addrinfo hints
, *servinfo
, *port
;
38 struct sockaddr_storage their_addr
;
41 char source
[INET6_ADDRSTRLEN
];
45 memset(&hints
, 0, sizeof hints
);
46 hints
.ai_family
= AF_INET
;
47 hints
.ai_socktype
= SOCK_STREAM
;
48 hints
.ai_flags
= AI_PASSIVE
;
50 // look up local address information
51 if ((rv
= getaddrinfo(NULL
, PORT
, &hints
, &servinfo
)) != 0) {
52 fprintf(stderr
, "getaddrinfo: %s\n", gai_strerror(rv
));
56 // loop over available interfaces and try to bind to port
57 for (port
= servinfo
; port
!= NULL
; port
= port
->ai_next
) {
58 if ((sockfd
= socket(port
->ai_family
, port
->ai_socktype
,
59 port
->ai_protocol
)) == -1) {
60 perror("irssi-notify: socket");
63 if (setsockopt(sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
,
68 if (bind(sockfd
, port
->ai_addr
, port
->ai_addrlen
) == -1) {
70 perror("irssi-notify: bind");
77 fprintf(stderr
, "irssi-notify: failed to bind\n");
81 freeaddrinfo(servinfo
);
83 if (listen(sockfd
, QUEUE_LENGTH
) == -1) {
88 // bind sigchld_handler to reap future child processes
89 sa
.sa_handler
= sigchld_handler
;
90 sigemptyset(&sa
.sa_mask
);
91 sa
.sa_flags
= SA_RESTART
;
92 if (sigaction(SIGCHLD
, &sa
, NULL
) == -1) {
97 printf("irssi-notify: waiting for connections...\n");
100 sin_size
= sizeof their_addr
;
101 activefd
= accept(sockfd
, (struct sockaddr
*)&their_addr
, &sin_size
);
102 if (activefd
== -1) {
107 inet_ntop(their_addr
.ss_family
,
108 get_in_addr((struct sockaddr
*)&their_addr
),
109 source
, sizeof source
);
112 if (strcmp(source
, "50.16.219.8") != 0 &&
113 strcmp(source
, "127.0.0.1") != 0){
118 // start a child process to handle notifications
120 // the child process doesn't need the listener
123 if (recv(activefd
, buf
, 99, 0) == -1) {
128 printf("irssi-notify: recieved '%s'\n", buf
);
129 notify_init("irssi-notify");
130 NotifyNotification
* notification
=
131 notify_notification_new("", buf
, "irssi-notify");
132 notify_notification_show(notification
, NULL
);