summaryrefslogblamecommitdiffstats
path: root/helper.c
blob: 93ed207ad4f71470781950cba9d5bec08380e095 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                       
                                       
                     
 







                                

                       






















                                                                                                           
                                                    











                                                           
                                                                    




                                                                        
                                                    
                                         





                                                                                     






                             











                                                                     




                                                               
                                                                                 
 
                                                          
                                                    
                                                            
                
                             
         

 





                                                                       











                                                                         











                                                                                                      
                                                   
 



                                       



                                     
         


































                                                                         
                         
                                     
                 
                      



















                                                         
         




                                         
                      

 
                                                         
 
                                               






                                
#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>

DebugLevel _debugLevel = DEBUG_WARNING;
int _autoRestart = 0;

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 = helper_newSocket();
		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 = helper_newSocket();
		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;
}

int helper_newSocket()
{
	struct timeval tv;
	int sock = socket_tcp4b();
	if (sock == -1) return -1;
	tv.tv_sec = 4;
	tv.tv_usec = 0;
	setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
	setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
	return sock;
}

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);
	} else {
		putchar(')');
	}
}

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

void helper_printpal(struct PartialAttributeList *pal)
{
	printf("-- PAL --\n");
	while (pal) {
			printf("entry (");
			if (pal->type.l && pal->type.s) printf("%.*s", (int)pal->type.l, pal->type.s);
		printf("): ");
		helper_printal(pal->values);
		pal = pal->next;
	}
}

static void helper_printfilterInt(struct Filter* f)
{
	if (f == NULL) {
		printf("(nullfilter)");
		return;
	}
	while (f != NULL) {
		switch (f->type) {
		case AND:
			printf("(&");
mergesub:
			helper_printfilterInt(f->x);
			putchar(')');
			break;
		case OR:
			printf("(|");
			goto mergesub;
		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);
				s=s->next;
			}
			putchar(')');
		}
		break;
		case GREATEQUAL:
			helper_printavaInt(&f->ava,">=");
			break;
		case LESSEQUAL:
			helper_printavaInt(&f->ava,"<=");
			break;
		case PRESENT:
			f->ava.value.l = 0;
			helper_printavaInt(&f->ava,"=*");
			break;
		case APPROX:
			helper_printavaInt(&f->ava,"~=");
			break;
		case EXTENSIBLE:
			printf("[extensible]");
			break;
		default:
			printf("????????");
		}
		f = f->next;
	}
}

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

void plog(const DebugLevel messageLevel, char *args, ...)
{
	if (messageLevel > _debugLevel) return;
	va_list argList;
	va_start(argList, args);
	vprintf(args, argList);
	va_end(argList);
	putchar('\n');
	fflush(stdout);
}