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