7 #include <sys/socket.h>
8 #include <netinet/in.h>
17 // XXX move to config file
19 #define BACKLOG 3 // how many pending connections queue will hold
23 static void sigchld_handler (int s
)
25 while (waitpid(-1, NULL
, WNOHANG
) > 0);
30 static void init_signals (void)
34 sa
.sa_handler
= sigchld_handler
; // reap all dead processes
35 sigemptyset (&sa
.sa_mask
);
36 sa
.sa_flags
= SA_RESTART
;
37 if (sigaction(SIGCHLD
, &sa
, NULL
) == -1)
46 static int open_socket (int port
)
48 int sockfd
; // listen on sock_fd
49 struct sockaddr_in my_addr
; // my address information
52 if ((sockfd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
58 if (setsockopt(sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(int)) == -1)
60 perror ("setsockopt");
65 my_addr
.sin_family
= AF_INET
; // host byte order
66 my_addr
.sin_port
= htons(port
); // short, network byte order
67 my_addr
.sin_addr
.s_addr
= INADDR_ANY
; // automatically fill with my IP
68 memset (&(my_addr
.sin_zero
), 0, 8); // zero the rest of the struct
70 if (bind(sockfd
, (struct sockaddr
*)&my_addr
, sizeof(struct sockaddr
)) == -1)
77 if (listen(sockfd
, BACKLOG
) == -1)
97 * Handle newly connected client in a thread
99 static void* connection_thread (void *data
)
103 int sock
= ((thread_data
*)data
)->sock
;
106 send_telnet_init (sock
);
108 sess
= add_session(sock
);
112 remove_session (sess
);
119 static void handle_connect (int new_fd
)
121 pthread_attr_t thread_attr
;
125 if ((data
= malloc(sizeof(thread_data
))) == NULL
)
135 pthread_attr_init (&thread_attr
);
136 pthread_attr_setdetachstate (&thread_attr
, PTHREAD_CREATE_DETACHED
);
137 pthread_attr_setscope (&thread_attr
, PTHREAD_SCOPE_PROCESS
);
139 // handle new connection in a thread
140 if (pthread_create(&th
, &thread_attr
, connection_thread
, data
) != 0)
148 // socket used to listen for new connections
149 int server_socket
= -1;
155 server_socket
= open_socket(MYPORT
);
156 if (server_socket
== -1) return 1;
160 struct sockaddr_in their_addr
; // connector's address information
161 socklen_t sin_size
= sizeof(struct sockaddr_in
);
164 // got a new connection
165 if ((new_fd
= accept(server_socket
, (struct sockaddr
*)&their_addr
, &sin_size
)) == -1)
171 printf("server: got connection from %s\n",inet_ntoa(their_addr
.sin_addr
));
172 handle_connect (new_fd
);
175 close (server_socket
);
177 extern pthread_mutex_t sessionlist_mutex
;
178 pthread_mutex_destroy (&sessionlist_mutex
);