#include <signal.h>
#include <libnotify/notify.h>
-#define PORT "3490" // the port users will be connecting to
-
-#define BACKLOG 10 // how many pending connections queue will hold
+#define PORT "3490"
+#define QUEUE_LENGTH 10
+// a function to reap future child processes
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
-// get sockaddr, IPv4
+// look for an IPv4 host:port in an address structure
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
int main(void)
{
- int sockfd, activefd; // listen on sockfd, new connection on activefd
- struct addrinfo hints, *servinfo, *p;
- struct sockaddr_storage their_addr; // connector's address information
+ // new connections on activefd, always listening on sockfd
+ int sockfd, activefd;
+ struct addrinfo hints, *servinfo, *port;
+ struct sockaddr_storage their_addr;
socklen_t sin_size;
struct sigaction sa;
- int yes=1;
char source[INET6_ADDRSTRLEN];
-// char CLIENT_IP[15] = "107.21.205.69\0";
+ int yes=1;
int rv;
- memset(&hints, 0, sizeof hints); // make sure the struct is empty
- hints.ai_family = AF_INET; // IPv4
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE; // use my IP
+ hints.ai_flags = AI_PASSIVE;
+ // look up local address information
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
- // servinfo now points to a linked list of 1 or more struct addrinfos
-
- // loop through all the results and bind to the first we can
- for(p = servinfo; p != NULL; p = p->ai_next) {
- if ((sockfd = socket(p->ai_family, p->ai_socktype,
- p->ai_protocol)) == -1) {
+ // loop over available interfaces and try to bind to port
+ for (port = servinfo; port != NULL; port = port->ai_next) {
+ if ((sockfd = socket(port->ai_family, port->ai_socktype,
+ port->ai_protocol)) == -1) {
perror("irssi-notify: socket");
continue;
}
-
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
-
- if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+ if (bind(sockfd, port->ai_addr, port->ai_addrlen) == -1) {
close(sockfd);
perror("irssi-notify: bind");
continue;
}
-
break;
}
- if (p == NULL) {
+ if (port == NULL) {
fprintf(stderr, "irssi-notify: failed to bind\n");
return 2;
}
- freeaddrinfo(servinfo); // all done with this structure
+ freeaddrinfo(servinfo);
- if (listen(sockfd, BACKLOG) == -1) {
+ if (listen(sockfd, QUEUE_LENGTH) == -1) {
perror("listen");
exit(1);
}
- sa.sa_handler = sigchld_handler; // reap all dead processes
+ // bind sigchld_handler to reap future child processes
+ sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
printf("irssi-notify: waiting for connections...\n");
- while(1) { // main accept() loop
+ while (1) {
sin_size = sizeof their_addr;
activefd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (activefd == -1) {
get_in_addr((struct sockaddr *)&their_addr),
source, sizeof source);
+ // whitelist allowed
if (strcmp(source, "50.16.219.8") != 0 &&
strcmp(source, "127.0.0.1") != 0){
close(activefd);
continue;
}
- if (!fork()) { // this is the child process
- close(sockfd); // child doesn't need the listener
+ // start a child process to handle notifications
+ if (!fork()) {
+ // the child process doesn't need the listener
+ close(sockfd);
char buf[4096];
if (recv(activefd, buf, 99, 0) == -1) {
perror("recv");