mirror of
https://salsa.debian.org/ha-team/libqb
synced 2025-08-26 23:44:41 +00:00
155 lines
3.6 KiB
C
155 lines
3.6 KiB
C
/*
|
|
* Copyright (c) 2011 Red Hat, Inc.
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Author: Angus Salkeld <asalkeld@redhat.com>
|
|
*
|
|
* libqb is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* libqb is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "os_base.h"
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif /* HAVE_NETINET_IN_H */
|
|
#ifdef HAVE_ARPA_INET_H
|
|
#include <arpa/inet.h>
|
|
#endif /* HAVE_ARPA_INET_H */
|
|
#ifdef HAVE_NETDB_H
|
|
#include <netdb.h>
|
|
#endif /* HAVE_NETDB_H */
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
#include <sys/socket.h>
|
|
#endif /* HAVE_SYS_SOCKET_H */
|
|
#ifdef HAVE_SYS_POLL_H
|
|
#include <sys/poll.h>
|
|
#endif /* HAVE_SYS_POLL_H */
|
|
|
|
#include <qb/qbdefs.h>
|
|
#include <qb/qbloop.h>
|
|
|
|
static int32_t
|
|
sock_read_fn(int32_t fd, int32_t revents, void *data)
|
|
{
|
|
char recv_data[1024];
|
|
char send_data[1024];
|
|
int bytes_recieved;
|
|
|
|
if (revents & POLLHUP) {
|
|
printf("Socket %d peer closed\n", fd);
|
|
close(fd);
|
|
return QB_FALSE;
|
|
}
|
|
|
|
bytes_recieved = recv(fd, recv_data, 1024, 0);
|
|
if (bytes_recieved < 0) {
|
|
perror("recv");
|
|
return QB_TRUE;
|
|
}
|
|
recv_data[bytes_recieved] = '\0';
|
|
|
|
if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) {
|
|
printf("Quiting connection from socket %d\n", fd);
|
|
close(fd);
|
|
return QB_FALSE;
|
|
} else {
|
|
printf("Recieved: %s\n", recv_data);
|
|
snprintf(send_data, 1024, "ACK %d bytes", bytes_recieved);
|
|
if (send(fd, send_data, strlen(send_data), 0) < 0) {
|
|
close(fd);
|
|
return QB_FALSE;
|
|
}
|
|
}
|
|
return QB_TRUE;
|
|
}
|
|
|
|
static int32_t
|
|
sock_accept_fn(int32_t fd, int32_t revents, void *data)
|
|
{
|
|
struct sockaddr_in client_addr;
|
|
qb_loop_t *ml = (qb_loop_t *) data;
|
|
socklen_t sin_size = sizeof(struct sockaddr_in);
|
|
int connected = accept(fd, (struct sockaddr *)&client_addr, &sin_size);
|
|
|
|
if (connected < 0) {
|
|
perror("accept");
|
|
return QB_TRUE;
|
|
}
|
|
printf("I got a connection from (%s , %d)\n",
|
|
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
|
|
|
|
qb_loop_poll_add(ml, QB_LOOP_MED, connected, POLLIN, ml, sock_read_fn);
|
|
|
|
return QB_TRUE;
|
|
}
|
|
|
|
static int32_t
|
|
please_exit_fn(int32_t rsignal, void *data)
|
|
{
|
|
qb_loop_t *ml = (qb_loop_t *) data;
|
|
|
|
printf("Shutting down at you request...\n");
|
|
qb_loop_stop(ml);
|
|
return QB_FALSE;
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int sock;
|
|
int true_opt = 1;
|
|
struct sockaddr_in server_addr;
|
|
qb_loop_t *ml = qb_loop_create();
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
|
perror("Socket");
|
|
exit(1);
|
|
}
|
|
|
|
if (setsockopt(sock,
|
|
SOL_SOCKET,
|
|
SO_REUSEADDR, &true_opt, sizeof(int)) == -1) {
|
|
perror("Setsockopt");
|
|
exit(1);
|
|
}
|
|
|
|
server_addr.sin_family = AF_INET;
|
|
server_addr.sin_port = htons(5000);
|
|
server_addr.sin_addr.s_addr = INADDR_ANY;
|
|
bzero(&(server_addr.sin_zero), 8);
|
|
|
|
printf("TCPServer binding to port 5000\n");
|
|
if (bind(sock,
|
|
(struct sockaddr *)&server_addr,
|
|
sizeof(struct sockaddr)) == -1) {
|
|
perror("Unable to bind");
|
|
exit(1);
|
|
}
|
|
|
|
printf("TCPServer Waiting for client on port 5000\n");
|
|
|
|
if (listen(sock, 5) == -1) {
|
|
perror("Listen");
|
|
exit(1);
|
|
}
|
|
|
|
qb_loop_poll_add(ml, QB_LOOP_MED, sock, POLLIN, ml, sock_accept_fn);
|
|
|
|
qb_loop_signal_add(ml, QB_LOOP_HIGH, SIGINT, ml, please_exit_fn, NULL);
|
|
qb_loop_run(ml);
|
|
|
|
close(sock);
|
|
return 0;
|
|
}
|