#include "helper.h"
#include <socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <stdarg.h>
void bail(char *args, ...)
{
printf("ERROR: ");
va_list argList;
va_start(argList, args);
vprintf(args, argList);
va_end(argList);
printf("\n");
exit(1);
}
/**
* 0 = SUCCESS, -1 = ERROR
* on success, memory pointer and size variable will be updated.
*/
int helper_realloc(char **memory, size_t *curSize, const size_t newSize, const char *location)
{
void *newBlock = realloc(*memory, newSize);
if (newBlock == NULL) {
printf("OUT OF MEMORY when trying to realloc to %d bytes at %s\n", (int)newSize, location);
return -1;
}
*memory = newBlock;
if (curSize != NULL) *curSize = newSize;
return 0;
}
int helper_connect4(char *address, int port, char *ip)
{
if (sizeof(struct in_addr) != 4) bail("Ach nöö ach nöö");
if (inet_pton(AF_INET, address, ip) == 1) {
const int sock = socket_tcp4b();
if (sock == -1) return -1;
if (socket_connect4(sock, ip, port) == 0) {
return sock;
}
close(sock);
return -1;
}
struct addrinfo hints;
struct addrinfo *result, *rp;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
const int ret = getaddrinfo(NULL, address, &hints, &result);
if (ret != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
return -1;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
const int sock = socket_tcp4b();
if (sock == -1) continue;
memcpy(ip, rp->ai_addr->sa_data, 4);
if (socket_connect4(sock, ip, port) == 0) {
freeaddrinfo(result);
return sock; // Success
}
close(sock);
}
freeaddrinfo(result);
return -1;
}
void helper_nonblock(const int fd)
{
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
}
void helper_printava(struct AttributeValueAssertion* a,const char* rel)
{
putchar('[');
printf("%.*s", (int)a->desc.l,a->desc.s);
putchar(' ');
printf("%s", rel);
putchar(' ');
printf("%.*s", (int)a->value.l,a->value.s);
putchar(']');
}
void helper_printal(struct AttributeDescriptionList* a)
{
while (a) {
if (a->a.s && a->a.l) printf("%.*s", (int)a->a.l,a->a.s);
a=a->next;
if (a) {
putchar(',');
}
}
putchar('\n');
}
void helper_printfilter(struct Filter* f)
{
switch (f->type) {
case AND:
printf("&(");
mergesub:
helper_printfilter(f->x);
printf(")\n");
break;
case OR:
printf("|(");
goto mergesub;
break;
case NOT:
printf("!(");
goto mergesub;
case EQUAL:
helper_printava(&f->ava,"==");
break;
case SUBSTRING: {
struct Substring* s=f->substrings;
int first=1;
printf("%.*s",(int)f->ava.desc.l,f->ava.desc.s);
printf(" has ");
while (s) {
if (!first) {
printf(" and ");
}
first=0;
switch(s->substrtype) {
case prefix:
printf("prefix \"");
break;
case any:
printf("substr \"");
break;
case suffix:
printf("suffix \"");
break;
}
printf("%.*s",(int)s->s.l,s->s.s);
putchar('"');
s=s->next;
}
}
break;
case GREATEQUAL:
helper_printava(&f->ava,">=");
break;
case LESSEQUAL:
helper_printava(&f->ava,"<=");
break;
case PRESENT:
helper_printava(&f->ava,"\\exist");
break;
case APPROX:
helper_printava(&f->ava,"\\approx");
break;
case EXTENSIBLE:
printf("[extensible]");
break;
}
if (f->next) {
putchar(',');
helper_printfilter(f->next);
}
putchar('\n');
fflush(stdout);
}