7 #include <sys/socket.h>
8 #include <netinet/in.h>
10 #include <arpa/inet.h>
14 #define PORT "3490" // the port users will be connecting to
16 #define BACKLOG 10 // how many pending connections queue will hold
18 void sigchld_handler(int s
)
20 while(waitpid(-1, NULL
, WNOHANG
) > 0);
24 void *get_in_addr(struct sockaddr
*sa
)
26 if (sa
->sa_family
== AF_INET
) {
27 return &(((struct sockaddr_in
*)sa
)->sin_addr
);
33 int sockfd
, activefd
; // listen on sockfd, new connection on activefd
34 struct addrinfo hints
, *servinfo
, *p
;
35 struct sockaddr_storage their_addr
; // connector's address information
39 char source
[INET6_ADDRSTRLEN
];
40 // char CLIENT_IP[15] = "107.21.205.69\0";
43 memset(&hints
, 0, sizeof hints
); // make sure the struct is empty
44 hints
.ai_family
= AF_INET
; // IPv4
45 hints
.ai_socktype
= SOCK_STREAM
;
46 hints
.ai_flags
= AI_PASSIVE
; // use my IP
48 if ((rv
= getaddrinfo(NULL
, PORT
, &hints
, &servinfo
)) != 0) {
49 fprintf(stderr
, "getaddrinfo: %s\n", gai_strerror(rv
));
53 // servinfo now points to a linked list of 1 or more struct addrinfos
55 // loop through all the results and bind to the first we can
56 for(p
= servinfo
; p
!= NULL
; p
= p
->ai_next
) {
57 if ((sockfd
= socket(p
->ai_family
, p
->ai_socktype
,
58 p
->ai_protocol
)) == -1) {
59 perror("server: socket");
63 if (setsockopt(sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
,
69 if (bind(sockfd
, p
->ai_addr
, p
->ai_addrlen
) == -1) {
71 perror("server: bind");
79 fprintf(stderr
, "server: failed to bind\n");
83 freeaddrinfo(servinfo
); // all done with this structure
85 if (listen(sockfd
, BACKLOG
) == -1) {
90 sa
.sa_handler
= sigchld_handler
; // reap all dead processes
91 sigemptyset(&sa
.sa_mask
);
92 sa
.sa_flags
= SA_RESTART
;
93 if (sigaction(SIGCHLD
, &sa
, NULL
) == -1) {
98 printf("server: waiting for connections...\n");
100 while(1) { // main accept() loop
101 sin_size
= sizeof their_addr
;
102 activefd
= accept(sockfd
, (struct sockaddr
*)&their_addr
, &sin_size
);
103 if (activefd
== -1) {
108 inet_ntop(their_addr
.ss_family
,
109 get_in_addr((struct sockaddr
*)&their_addr
),
110 source
, sizeof source
);
112 if (strcmp(source
, "107.21.205.69") != 0 &&
113 strcmp(source
, "127.0.0.1") != 0){
118 if (!fork()) { // this is the child process
119 close(sockfd
); // child doesn't need the listener
121 if (recv(activefd
, buf
, 99, 0) == -1) {
126 printf("server: recieved '%s'\n", buf
);
128 setenv("DISPLAY", ":0", 1); // doesn't seem to be doing the trick
129 execl("notify-display",
130 "notify-display", buf
, NULL
);
131 // the first argument to execl is the command, the second is the first argument
132 // passed to the program ($0), customarily the evocation of the command