Cleanup
Separate out functions/structs/constants/globals to properly named files.
This commit is contained in:
parent
8b0363a059
commit
cadaf66cae
12 changed files with 249 additions and 151 deletions
8
Makefile
8
Makefile
|
@ -9,7 +9,13 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
src/main.c
|
src/main.c \
|
||||||
|
src/arg_parse.c \
|
||||||
|
src/big_endian.c \
|
||||||
|
src/tcp_socket.c \
|
||||||
|
src/signal_handling.c \
|
||||||
|
src/globals.c
|
||||||
|
|
||||||
OBJECT_DIR = objs
|
OBJECT_DIR = objs
|
||||||
OBJECTS = $(addprefix ${OBJECT_DIR}/,$(patsubst %.c,%.c.o,${SOURCES}))
|
OBJECTS = $(addprefix ${OBJECT_DIR}/,$(patsubst %.c,%.c.o,${SOURCES}))
|
||||||
|
|
||||||
|
|
42
src/arg_parse.c
Normal file
42
src/arg_parse.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include "arg_parse.h"
|
||||||
|
|
||||||
|
// Standard library includes.
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void print_usage(void) {
|
||||||
|
puts("Usage:");
|
||||||
|
puts(" -p <port> | --port <port>");
|
||||||
|
}
|
||||||
|
|
||||||
|
Args parse_args(int argc, char **argv) {
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
|
||||||
|
Args args;
|
||||||
|
memset(&args, 0, sizeof(Args));
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
if ((strcmp(argv[0], "-p") == 0 || strcmp(argv[0], "--port") == 0)
|
||||||
|
&& argc > 1) {
|
||||||
|
int value = atoi(argv[1]);
|
||||||
|
if (value >= 0 && value <= 0xFFFF) {
|
||||||
|
args.port = (unsigned short) value;
|
||||||
|
}
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
} else {
|
||||||
|
puts("ERROR: Invalid args!\n");
|
||||||
|
print_usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
15
src/arg_parse.h
Normal file
15
src/arg_parse.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_ARG_PARSE_H_
|
||||||
|
#define SEODISPARATE_COM_C_SIMPLE_HTTP_ARG_PARSE_H_
|
||||||
|
|
||||||
|
typedef struct Args {
|
||||||
|
unsigned short flags;
|
||||||
|
unsigned short port;
|
||||||
|
} Args;
|
||||||
|
|
||||||
|
void print_usage(void);
|
||||||
|
|
||||||
|
Args parse_args(int argc, char **argv);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
20
src/big_endian.c
Normal file
20
src/big_endian.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "big_endian.h"
|
||||||
|
|
||||||
|
int is_big_endian(void) {
|
||||||
|
union {
|
||||||
|
int i;
|
||||||
|
char c[4];
|
||||||
|
} bint = {0x01020304};
|
||||||
|
|
||||||
|
return bint.c[0] == 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short u16_be_swap(unsigned short value) {
|
||||||
|
if (is_big_endian()) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return ((value >> 8) & 0xFF) | ((value << 8) & 0xFF00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
10
src/big_endian.h
Normal file
10
src/big_endian.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_BIG_ENDIAN_H_
|
||||||
|
#define SEODISPARATE_COM_C_SIMPLE_HTTP_BIG_ENDIAN_H_
|
||||||
|
|
||||||
|
int is_big_endian(void);
|
||||||
|
|
||||||
|
unsigned short u16_be_swap(unsigned short value);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
5
src/globals.c
Normal file
5
src/globals.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
int C_SIMPLE_HTTP_KEEP_RUNNING = 1;
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
8
src/globals.h
Normal file
8
src/globals.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_GLOBALS_H_
|
||||||
|
#define SEODISPARATE_COM_C_SIMPLE_HTTP_GLOBALS_H_
|
||||||
|
|
||||||
|
extern int C_SIMPLE_HTTP_KEEP_RUNNING;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
157
src/main.c
157
src/main.c
|
@ -4,161 +4,18 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// Unix includes.
|
// Unix includes.
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define C_SIMPLE_HTTP_TCP_SOCKET_BACKLOG 64
|
// Local includes.
|
||||||
|
#include "arg_parse.h"
|
||||||
|
#include "big_endian.h"
|
||||||
|
#include "tcp_socket.h"
|
||||||
|
#include "signal_handling.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
#define C_SIMPLE_HTTP_SLEEP_NANOS 1000000
|
#define C_SIMPLE_HTTP_SLEEP_NANOS 1000000
|
||||||
|
|
||||||
static int C_SIMPLE_HTTP_KEEP_RUNNING = 1;
|
|
||||||
|
|
||||||
void C_SIMPLE_HTTP_handle_sigint(int signal) {
|
|
||||||
if (signal == SIGINT) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
puts("Handling SIGINT");
|
|
||||||
#endif
|
|
||||||
C_SIMPLE_HTTP_KEEP_RUNNING = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct Args {
|
|
||||||
unsigned short flags;
|
|
||||||
unsigned short port;
|
|
||||||
} Args;
|
|
||||||
|
|
||||||
int is_big_endian(void) {
|
|
||||||
union {
|
|
||||||
int i;
|
|
||||||
char c[4];
|
|
||||||
} bint = {0x01020304};
|
|
||||||
|
|
||||||
return bint.c[0] == 1 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short u16_be_swap(unsigned short value) {
|
|
||||||
if (is_big_endian()) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
return ((value >> 8) & 0xFF) | ((value << 8) & 0xFF00);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int create_tcp_socket(unsigned short port) {
|
|
||||||
struct sockaddr_in6 ipv6_addr;
|
|
||||||
memset(&ipv6_addr, 0, sizeof(struct sockaddr_in6));
|
|
||||||
ipv6_addr.sin6_family = AF_INET6;
|
|
||||||
ipv6_addr.sin6_port = u16_be_swap(port);
|
|
||||||
ipv6_addr.sin6_addr = in6addr_any;
|
|
||||||
|
|
||||||
int tcp_socket = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 6);
|
|
||||||
|
|
||||||
if (tcp_socket == -1) {
|
|
||||||
switch (errno) {
|
|
||||||
case EACCES:
|
|
||||||
puts("ERROR: Socket creation: EACCES");
|
|
||||||
break;
|
|
||||||
case EAFNOSUPPORT:
|
|
||||||
puts("ERROR: Socket creation: EAFNOSUPPORT");
|
|
||||||
break;
|
|
||||||
case EINVAL:
|
|
||||||
puts("ERROR: Socket creation: EINVAL");
|
|
||||||
break;
|
|
||||||
case EMFILE:
|
|
||||||
puts("ERROR: Socket creation: EMFILE");
|
|
||||||
break;
|
|
||||||
case ENOBUFS:
|
|
||||||
puts("ERROR: Socket creation: ENOBUFS");
|
|
||||||
break;
|
|
||||||
case ENOMEM:
|
|
||||||
puts("ERROR: Socket creation: ENOMEM");
|
|
||||||
break;
|
|
||||||
case EPROTONOSUPPORT:
|
|
||||||
puts("ERROR: Socket creation: EPROTONOSUPPORT");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts("ERROR: Socket creation: Unknown Error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = bind(tcp_socket, (const struct sockaddr *)&ipv6_addr, sizeof(struct sockaddr_in6));
|
|
||||||
if (ret != 0) {
|
|
||||||
close(tcp_socket);
|
|
||||||
puts("ERROR: Failed to bind socket!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = listen(tcp_socket, C_SIMPLE_HTTP_TCP_SOCKET_BACKLOG);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
return tcp_socket;
|
|
||||||
} else {
|
|
||||||
switch (errno) {
|
|
||||||
case EADDRINUSE:
|
|
||||||
puts("ERROR: Socket listen: EADDRINUSE");
|
|
||||||
break;
|
|
||||||
case EBADF:
|
|
||||||
puts("ERROR: Socket listen: EBADF");
|
|
||||||
break;
|
|
||||||
case ENOTSOCK:
|
|
||||||
puts("ERROR: Socket listen: ENOTSOCK");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts("ERROR: Socket listen: Unknown Error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanup_tcp_socket(int *tcp_socket) {
|
|
||||||
if (tcp_socket && *tcp_socket != -1) {
|
|
||||||
close(*tcp_socket);
|
|
||||||
*tcp_socket = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_usage(void) {
|
|
||||||
puts("Usage:");
|
|
||||||
puts(" -p <port> | --port <port>");
|
|
||||||
}
|
|
||||||
|
|
||||||
Args parse_args(int argc, char **argv) {
|
|
||||||
--argc;
|
|
||||||
++argv;
|
|
||||||
|
|
||||||
Args args;
|
|
||||||
memset(&args, 0, sizeof(Args));
|
|
||||||
|
|
||||||
while (argc > 0) {
|
|
||||||
if ((strcmp(argv[0], "-p") == 0 || strcmp(argv[0], "--port") == 0)
|
|
||||||
&& argc > 1) {
|
|
||||||
int value = atoi(argv[1]);
|
|
||||||
if (value >= 0 && value <= 0xFFFF) {
|
|
||||||
args.port = (unsigned short) value;
|
|
||||||
}
|
|
||||||
--argc;
|
|
||||||
++argv;
|
|
||||||
} else {
|
|
||||||
puts("ERROR: Invalid args!\n");
|
|
||||||
print_usage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
--argc;
|
|
||||||
++argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Args args = parse_args(argc, argv);
|
Args args = parse_args(argc, argv);
|
||||||
|
|
||||||
|
|
21
src/signal_handling.c
Normal file
21
src/signal_handling.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "signal_handling.h"
|
||||||
|
|
||||||
|
// Standard library includes.
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Unix includes.
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
// Local includes
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
void C_SIMPLE_HTTP_handle_sigint(int signal) {
|
||||||
|
if (signal == SIGINT) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
puts("Handling SIGINT");
|
||||||
|
#endif
|
||||||
|
C_SIMPLE_HTTP_KEEP_RUNNING = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
8
src/signal_handling.h
Normal file
8
src/signal_handling.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_SIGNAL_HANDLING_H_
|
||||||
|
#define SEODISPARATE_COM_C_SIMPLE_HTTP_SIGNAL_HANDLING_H_
|
||||||
|
|
||||||
|
void C_SIMPLE_HTTP_handle_sigint(int signal);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
94
src/tcp_socket.c
Normal file
94
src/tcp_socket.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "tcp_socket.h"
|
||||||
|
|
||||||
|
// Standard library includes.
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Unix includes.
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Local includes.
|
||||||
|
#include "big_endian.h"
|
||||||
|
|
||||||
|
int create_tcp_socket(unsigned short port) {
|
||||||
|
struct sockaddr_in6 ipv6_addr;
|
||||||
|
memset(&ipv6_addr, 0, sizeof(struct sockaddr_in6));
|
||||||
|
ipv6_addr.sin6_family = AF_INET6;
|
||||||
|
ipv6_addr.sin6_port = u16_be_swap(port);
|
||||||
|
ipv6_addr.sin6_addr = in6addr_any;
|
||||||
|
|
||||||
|
int tcp_socket = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 6);
|
||||||
|
|
||||||
|
if (tcp_socket == -1) {
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES:
|
||||||
|
puts("ERROR: Socket creation: EACCES");
|
||||||
|
break;
|
||||||
|
case EAFNOSUPPORT:
|
||||||
|
puts("ERROR: Socket creation: EAFNOSUPPORT");
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
puts("ERROR: Socket creation: EINVAL");
|
||||||
|
break;
|
||||||
|
case EMFILE:
|
||||||
|
puts("ERROR: Socket creation: EMFILE");
|
||||||
|
break;
|
||||||
|
case ENOBUFS:
|
||||||
|
puts("ERROR: Socket creation: ENOBUFS");
|
||||||
|
break;
|
||||||
|
case ENOMEM:
|
||||||
|
puts("ERROR: Socket creation: ENOMEM");
|
||||||
|
break;
|
||||||
|
case EPROTONOSUPPORT:
|
||||||
|
puts("ERROR: Socket creation: EPROTONOSUPPORT");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("ERROR: Socket creation: Unknown Error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = bind(tcp_socket, (const struct sockaddr *)&ipv6_addr, sizeof(struct sockaddr_in6));
|
||||||
|
if (ret != 0) {
|
||||||
|
close(tcp_socket);
|
||||||
|
puts("ERROR: Failed to bind socket!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = listen(tcp_socket, C_SIMPLE_HTTP_TCP_SOCKET_BACKLOG);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
return tcp_socket;
|
||||||
|
} else {
|
||||||
|
switch (errno) {
|
||||||
|
case EADDRINUSE:
|
||||||
|
puts("ERROR: Socket listen: EADDRINUSE");
|
||||||
|
break;
|
||||||
|
case EBADF:
|
||||||
|
puts("ERROR: Socket listen: EBADF");
|
||||||
|
break;
|
||||||
|
case ENOTSOCK:
|
||||||
|
puts("ERROR: Socket listen: ENOTSOCK");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("ERROR: Socket listen: Unknown Error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup_tcp_socket(int *tcp_socket) {
|
||||||
|
if (tcp_socket && *tcp_socket != -1) {
|
||||||
|
close(*tcp_socket);
|
||||||
|
*tcp_socket = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
12
src/tcp_socket.h
Normal file
12
src/tcp_socket.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_TCP_SOCKET_H_
|
||||||
|
#define SEODISPARATE_COM_C_SIMPLE_HTTP_TCP_SOCKET_H_
|
||||||
|
|
||||||
|
#define C_SIMPLE_HTTP_TCP_SOCKET_BACKLOG 64
|
||||||
|
|
||||||
|
int create_tcp_socket(unsigned short port);
|
||||||
|
|
||||||
|
void cleanup_tcp_socket(int *tcp_socket);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vim: ts=2 sts=2 sw=2
|
Loading…
Reference in a new issue