summaryrefslogblamecommitdiffstats
path: root/helper.c
blob: 8dec6e41b0c80696208ea97ca1d3997b54bb3b82 (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");
	fflush(stdout);
	fflush(stderr);
	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(address, NULL, &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;
		if (rp->ai_addr != NULL) {
			memcpy(ip, &((struct sockaddr_in*)rp->ai_addr)->sin_addr, 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);
}

static void helper_printavaInt(struct AttributeValueAssertion* a,const char* rel)
{
	printf("[%.*s %s", (int)a->desc.l, a->desc.s, rel);
	if (a->value.l != 0 && a->value.s != NULL) {
		printf(" %.*s]", (int)a->value.l,a->value.s);
	}
}

void helper_printava(struct AttributeValueAssertion* a,const char* rel)
{
	helper_printavaInt(a, rel);
	putchar('\n');
}

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

static void helper_printfilterInt(struct Filter* f)
{
	switch (f->type) {
	case AND:
		printf("&(");
mergesub:
		helper_printfilterInt(f->x);
		printf(")");
		break;
	case OR:
		printf("|(");
		goto mergesub;
		break;
	case NOT:
		printf("!(");
		goto mergesub;
	case EQUAL:
		helper_printavaInt(&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_printavaInt(&f->ava,">=");
		break;
	case LESSEQUAL:
		helper_printavaInt(&f->ava,"<=");
		break;
	case PRESENT:
		helper_printavaInt(&f->ava,"\\exist");
		break;
	case APPROX:
		helper_printavaInt(&f->ava,"\\approx");
		break;
	case EXTENSIBLE:
		printf("[extensible]");
		break;
	}
	if (f->next) {
		putchar(',');
		helper_printfilterInt(f->next);
	}
}

void helper_printfilter(struct Filter* f)
{
	helper_printfilterInt(f);
	putchar('\n');
}