#include "helper.h" #include #include #include #include #include #include #include #include #include #include #include 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); }