Reformat codebase

This commit is contained in:
Tim Schubert 2018-10-29 10:30:10 +01:00
parent 3354826dec
commit a8757731b3

517
netcalc.c
View file

@ -16,324 +16,311 @@ int SOCKFD;
int CLIENT; int CLIENT;
void cleanup(int signum) void cleanup(int signum) {
{ if (close(SOCKFD) != 0) {
if (close(SOCKFD) != 0) { perror("close");
perror("close"); }
} exit(1);
exit(1);
} }
int prepaddr(char *host, char *port, struct addrinfo **ainfo, int afamily, int flags) int prepaddr(char *host, char *port, struct addrinfo **ainfo, int afamily, int flags) {
{ struct addrinfo hints; // hints to what we want
struct addrinfo hints; // hints to what we want memset(&hints, 0, sizeof hints);
memset(&hints, 0, sizeof hints); hints.ai_family = afamily; // AF_INET or AF_INET6 to force version
hints.ai_family = afamily; // AF_INET or AF_INET6 to force version hints.ai_socktype = SOCK_STREAM;
hints.ai_socktype = SOCK_STREAM; hints.ai_flags = flags;
hints.ai_flags = flags;
int status; int status;
if ((status = getaddrinfo(host, port, &hints, ainfo)) != 0) { if ((status = getaddrinfo(host, port, &hints, ainfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return -1; return -1;
} }
return 0; return 0;
} }
int bindsocket(int sockd, struct addrinfo *ainfo) int bindsocket(int sockd, struct addrinfo *ainfo) {
{ if (bind(SOCKFD, ainfo->ai_addr, ainfo->ai_addrlen) != 0) {
if (bind(SOCKFD, ainfo->ai_addr, ainfo->ai_addrlen) != 0) { perror("bind");
perror("bind"); cleanup(0);
cleanup(0); return -1;
return -1; }
}
if (listen(SOCKFD, 5) != 0) { if (listen(SOCKFD, 5) != 0) {
perror("listen"); perror("listen");
cleanup(0); cleanup(0);
return -1; return -1;
} }
return sockd; return sockd;
} }
int prepsocket(struct addrinfo *ainfo) int prepsocket(struct addrinfo *ainfo) {
{ SOCKFD = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
SOCKFD = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (SOCKFD == -1) { if (SOCKFD == -1) {
perror("socket"); perror("socket");
return -1; return -1;
} }
int yes = 1; int yes = 1;
if (setsockopt(SOCKFD, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) { if (setsockopt(SOCKFD, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
perror("setsockopt"); perror("setsockopt");
cleanup(0); cleanup(0);
return -1; return -1;
} }
return SOCKFD; return SOCKFD;
} }
int calc(unsigned int num1, unsigned int num2, char op, unsigned int *result) int calc(unsigned int num1, unsigned int num2, char op, unsigned int *result) {
{ switch (op) {
switch (op) { case '+':
case '+': if (__builtin_uadd_overflow(num1, num2, result)) {
if (__builtin_uadd_overflow(num1, num2, result)) { return -1;
return -1; }
} break;
break; case '-':
case '-': if (__builtin_usub_overflow(num1, num2, result)) {
if (__builtin_usub_overflow(num1, num2, result)) { return -1;
return -1; }
} break;
break; case '*':
case '*': if (__builtin_umul_overflow(num1, num2, result)) {
if (__builtin_umul_overflow(num1, num2, result)) { return -1;
return -1; }
} break;
break; case '/':
case '/': if (num1 == 0 || num2 == 0) {
if (num1 == 0 || num2 == 0) { return -1;
return -1; }
} *result = num1 / num2;
*result = num1 / num2; break;
break; default:
default: return -1;
return -1; }
} return 0;
return 0;
} }
int base(char *numstr, unsigned int *num) int base(char *numstr, unsigned int *num) {
{ short base = 10;
short base = 10;
size_t len = strlen(numstr); size_t len = strlen(numstr);
if (len > 1 && numstr[len-1] == 'b') { if (len > 1 && numstr[len-1] == 'b') {
base = 2; base = 2;
} else if (len > 2 && numstr[0] == '0' && numstr[1] == 'x') { } else if (len > 2 && numstr[0] == '0' && numstr[1] == 'x') {
base = 16; base = 16;
} }
unsigned long test = strtoul(numstr, NULL, base); unsigned long test = strtoul(numstr, NULL, base);
if (test <= UINT_MAX) { if (test <= UINT_MAX) {
*num = (unsigned int) test; *num = (unsigned int) test;
return base; return base;
} else { } else {
return 0; return 0;
} }
} }
int parse(char *buf, size_t buflen, unsigned int *first, unsigned int *second, char *op) int parse(char *buf, size_t buflen, unsigned int *first, unsigned int *second, char *op) {
{ char *num1str = NULL;
char *num1str = NULL; char *num2str = NULL;
char *num2str = NULL; char *opstr = NULL;
char *opstr = NULL;
ssize_t num_items = sscanf(buf, "%m[x0-9A-Fb]%m[+-*/]%m[x0-9A-Fb]", &num1str, &opstr, &num2str); ssize_t num_items = sscanf(buf, "%m[x0-9A-Fb]%m[+-*/]%m[x0-9A-Fb]", &num1str, &opstr, &num2str);
int status = 0; int status = 0;
if (num_items < 3) { if (num_items < 3) {
if (num_items == 1 && base(num1str, first) > 0) { if (num_items == 1 && base(num1str, first) > 0) {
status = -2; status = -2;
} else { } else {
status = -1; status = -1;
} }
} else if (base(num2str, second) == 0 || base(num1str, first) == 0) { } else if (base(num2str, second) == 0 || base(num1str, first) == 0) {
status = -1; status = -1;
} }
if (opstr) { if (opstr) {
*op = opstr[0]; *op = opstr[0];
} }
free(num1str); free(num1str);
free(num2str); free(num2str);
free(opstr); free(opstr);
return status; return status;
} }
void report_error(char *buf, unsigned long buflen, char *msg) void report_error(char *buf, unsigned long buflen, char *msg) {
{ fprintf(stderr, "%s\n", msg);
fprintf(stderr, "%s\n", msg); memset(buf, 0, buflen);
memset(buf, 0, buflen); sprintf(buf, "%s\n", msg);
sprintf(buf, "%s\n", msg);
} }
void bstr(unsigned int n, char **out) void bstr(unsigned int n, char **out) {
{ // voodoo
// voodoo int msb = 32 - __builtin_clz(n);
int msb = 32 - __builtin_clz(n); (*out) = (char*) calloc(msb+1, sizeof (char));
(*out) = (char*) calloc(msb+1, sizeof (char)); (*out)[msb] = '\0';
(*out)[msb] = '\0'; for (msb = msb-1; msb >= 0; msb--) {
for (msb = msb-1; msb >= 0; msb--) { (*out)[msb] = (char) (48 + n % 2);
(*out)[msb] = (char) (48 + n % 2); n = n/2;
n = n/2; }
}
} }
int server() int server() {
{ struct sockaddr_storage c_addr;
struct sockaddr_storage c_addr; socklen_t sin_size = sizeof c_addr;
socklen_t sin_size = sizeof c_addr; while (1) {
while (1) { int c_fd = accept(SOCKFD, (struct sockaddr *)&c_addr, &sin_size);
int c_fd = accept(SOCKFD, (struct sockaddr *)&c_addr, &sin_size);
if (c_fd == -1) { if (c_fd == -1) {
perror("accept"); perror("accept");
continue; // we do not care continue; // we do not care
} }
char buf[BUFLEN]; char buf[BUFLEN];
ssize_t byte_count; ssize_t byte_count;
while ((byte_count = recv(c_fd, buf, sizeof buf, 0)) != 0) { while ((byte_count = recv(c_fd, buf, sizeof buf, 0)) != 0) {
if (byte_count == -1) { if (byte_count == -1) {
perror("recv"); perror("recv");
break; break;
} }
unsigned int first; unsigned int first;
unsigned int second; unsigned int second;
char op; char op;
unsigned int result; unsigned int result;
if (parse(buf, sizeof buf, &first, &second, &op) < 0) { if (parse(buf, sizeof buf, &first, &second, &op) < 0) {
report_error(buf, BUFLEN, "parse: failed to parse"); report_error(buf, BUFLEN, "parse: failed to parse");
} else if (calc(first, second, op, &result) == -1) { } else if (calc(first, second, op, &result) == -1) {
report_error(buf, BUFLEN, "calc: failed to calculate"); report_error(buf, BUFLEN, "calc: failed to calculate");
} else { } else {
memset(buf, 0, sizeof buf); memset(buf, 0, sizeof buf);
char *bin; char *bin;
bstr(result, &bin); bstr(result, &bin);
sprintf(buf, "%u 0x%X %sb\n", result, result, bin); sprintf(buf, "%u 0x%X %sb\n", result, result, bin);
free(bin); free(bin);
} }
if (send(c_fd, buf, strlen(buf)+1, 0) == -1) { if (send(c_fd, buf, strlen(buf)+1, 0) == -1) {
perror("send"); perror("send");
continue; continue;
} }
} }
close(c_fd); close(c_fd);
} }
} }
int connectclient(struct addrinfo *ainfo) int connectclient(struct addrinfo *ainfo) {
{ if (connect(SOCKFD, ainfo->ai_addr, ainfo->ai_addrlen) == -1) {
if (connect(SOCKFD, ainfo->ai_addr, ainfo->ai_addrlen) == -1) { perror("connect");
perror("connect"); return -1;
return -1; }
} return 0;
return 0;
} }
int client() int client() {
{ char buf[BUFLEN];
char buf[BUFLEN]; size_t nullsize = 0;
size_t nullsize = 0; char *line = NULL;
char *line = NULL; while (getline(&line, &nullsize, stdin) != -1) {
while (getline(&line, &nullsize, stdin) != -1) { unsigned int num1;
unsigned int num1; unsigned int num2;
unsigned int num2; char op;
char op;
memset(buf, 0, BUFLEN); memset(buf, 0, BUFLEN);
int status = parse(line, strlen(line)+1, &num1, &num2, &op); int status = parse(line, strlen(line)+1, &num1, &num2, &op);
if (status == -1) { if (status == -1) {
report_error(buf, BUFLEN, "parse: failed to parse"); report_error(buf, BUFLEN, "parse: failed to parse");
continue; continue;
} else if (status == -2) { } else if (status == -2) {
sprintf(buf, "%u%c%s", num1, '+', "0"); sprintf(buf, "%u%c%s", num1, '+', "0");
} else { } else {
sprintf(buf, "%u%c%u", num1, op, num2); sprintf(buf, "%u%c%u", num1, op, num2);
} }
if (send(SOCKFD, buf, strlen(buf)+1, 0) == -1) { if (send(SOCKFD, buf, strlen(buf)+1, 0) == -1) {
perror("send"); perror("send");
continue; continue;
} }
free(line); free(line);
line = NULL; // so getline allocates a buffer for us line = NULL; // so getline allocates a buffer for us
memset(buf, 0, BUFLEN); memset(buf, 0, BUFLEN);
ssize_t re_bytes_c = recv(SOCKFD, buf, sizeof buf, 0); ssize_t re_bytes_c = recv(SOCKFD, buf, sizeof buf, 0);
if (re_bytes_c == -1) { if (re_bytes_c == -1) {
perror("recv"); perror("recv");
continue; continue;
} }
printf("%s", buf); printf("%s", buf);
} }
return 0; return 0;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ SOCKFD = 0;
SOCKFD = 0; struct sigaction action;
struct sigaction action; memset(&action, 0, sizeof(struct sigaction));
memset(&action, 0, sizeof(struct sigaction)); action.sa_handler = cleanup;
action.sa_handler = cleanup; sigaction(SIGTERM, &action, NULL);
sigaction(SIGTERM, &action, NULL);
char* host = NULL; char* host = NULL;
char* port = "5000"; char* port = "5000";
int afamiliy = AF_UNSPEC; int afamiliy = AF_UNSPEC;
int flags = 0; int flags = 0;
if (argc > 1 && strcmp(argv[1], "-c") == 0) { if (argc > 1 && strcmp(argv[1], "-c") == 0) {
CLIENT = 1; // client mode CLIENT = 1; // client mode
if (argc > 2) { if (argc > 2) {
host = argv[2]; host = argv[2];
if (argc > 3) { if (argc > 3) {
port = argv[3]; port = argv[3];
} }
} }
} else if (argc > 1 && strcmp(argv[1], "-h") == 0) { } else if (argc > 1 && strcmp(argv[1], "-h") == 0) {
printf("usage: netcalc [-c hostname] [port]\n"); printf("usage: netcalc [-c hostname] [port]\n");
return 0; return 0;
} else { } else {
CLIENT = 0; CLIENT = 0;
afamiliy = AF_INET6; afamiliy = AF_INET6;
flags |= AI_PASSIVE; flags |= AI_PASSIVE;
if (argc > 1) { if (argc > 1) {
port = argv[1]; port = argv[1];
} }
} }
struct addrinfo *ainfo; struct addrinfo *ainfo;
if (prepaddr(host, port, &ainfo, afamiliy, flags) != 0) { if (prepaddr(host, port, &ainfo, afamiliy, flags) != 0) {
fprintf(stderr, "prepaddr: failed to obtain adress.\n"); fprintf(stderr, "prepaddr: failed to obtain adress.\n");
return 1; return 1;
} }
if ((SOCKFD = prepsocket(ainfo)) == -1) { if ((SOCKFD = prepsocket(ainfo)) == -1) {
return 1; return 1;
} }
if (CLIENT) { if (CLIENT) {
connectclient(ainfo); connectclient(ainfo);
if (client() == -1) { if (client() == -1) {
fprintf(stderr, "client: error"); fprintf(stderr, "client: error");
} }
} else { } else {
if ((SOCKFD = bindsocket(SOCKFD, ainfo)) == -1) { if ((SOCKFD = bindsocket(SOCKFD, ainfo)) == -1) {
fprintf(stderr, "bindsocket: failed to bind or listen."); fprintf(stderr, "bindsocket: failed to bind or listen.");
return 1; return 1;
} }
if (server() == -1) { if (server() == -1) {
fprintf(stderr, "server: error"); fprintf(stderr, "server: error");
} }
} }
freeaddrinfo(ainfo); // free the linked list freeaddrinfo(ainfo); // free the linked list
if (close(SOCKFD) != 0) { if (close(SOCKFD) != 0) {
perror("close"); perror("close");
} }
return 0; return 0;
} }