summaryrefslogblamecommitdiffstats
path: root/helper.c
blob: 1ba11b08efdbf50de94a4b29fb222d8c815bc4da (plain) (tree)













































































































































































                                                                                                           
#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);
}