commit 7bd71cfec50188577638168c3a0f14fcc855a19a Author: LongHairedHacker Date: Wed Sep 9 19:37:00 2015 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8efbdf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.swp +*.swo +*.o + +bin/ + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..87ca985 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "twinkl"] + path = twinkl + url = git@github.com:LongHairedHacker/twinkl.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..97475a4 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +TARGET = twinkl-client +SRC = main.c twinklsocket.c +HEADERS = include/twinklsocket.h +OBJDIR = bin + +CC = clang +CFLAGS = -Wall -O2 -I include -I twinkl/include +LDFLAGS = + +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) + + +all : start $(OBJDIR)/$(TARGET) + @echo ":: Done !" + +start : + @echo "twinkl-client" + @echo "=============" + @echo ":: Building using $(CC)" + @echo ":: Twinkl revision $(shell cd twinkl; git rev-parse --short HEAD)" + @echo ":: Twinkel-client revision $(shell git rev-parse --short HEAD)" + + +$(OBJDIR)/%.o : %.c Makefile $(HEADERS) + mkdir -p $$(dirname $@) + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/$(TARGET) : $(OBJ) + $(CC) $+ $(LDFLAGS) -o $@ + +clean : + @rm -rf $(OBJDIR) + +run : $(OBJDIR)/$(TARGET) + $(OBJDIR)/$(TARGET) diff --git a/include/twinklsocket.h b/include/twinklsocket.h new file mode 100644 index 0000000..831c5dc --- /dev/null +++ b/include/twinklsocket.h @@ -0,0 +1,12 @@ +#ifndef _TWINKLSOCKET_H +#define _TWINKLSOCKET_H + +#include "message.h" + +int twinklsocket_open(const char *host, const char *port); + +void twinklsocket_send(int sockfd, const struct twinkl_message *message); + +void twinklsocket_close(int sockfd); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..bf9f5aa --- /dev/null +++ b/main.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "message.h" +#include "twinklsocket.h" + +const char port[] = "1337"; + +int main(int argc, char *argv[]) +{ + int twinklsocket; + + if(argc != 3) { + fprintf(stderr,"usage: %s hostname priority\n", argv[0]); + exit(1); + } + + twinklsocket = twinklsocket_open(argv[1], port); + + struct twinkl_message msg; + twinkl_init_message(&msg); + + unsigned long priority; + priority = strtoul(argv[2], NULL, 0); + if(priority == ULONG_MAX || priority > TWINKL_LEVEL_COUNT) { + fprintf(stderr, "Priority not in range 0..%d\n", TWINKL_LEVEL_COUNT); + exit(1); + } + + int linecount = 0; + size_t len = 0; + char *line = NULL; + + /* + * Line format: : + * With abitrary many spaces btween the numbers and the colon + * Example: "5 : 42" + */ + while(getline(&line, &len, stdin) > 1) { + char *colon, *end; + unsigned long chan, value; + + linecount++; + + chan = strtoul(line, &end, 0); + if(chan == ULONG_MAX || end == line) { + fprintf(stderr, "Invalid channel number for line %d\n", linecount); + continue; + } + if(chan > TWINKL_CHANNEL_COUNT) { + fprintf(stderr, "Channel number %lu not in range 0..%d for line %d\n", + chan, + TWINKL_CHANNEL_COUNT - 1, + linecount); + + continue; + } + + colon = strchr(end, ':'); + if(colon == NULL) { + fprintf(stderr, "Missing delimiter in line %d\n", linecount); + continue; + } + + // First char after the colon is value + value = strtoul(colon + 1, &end, 0); + if(value == ULONG_MAX || end == colon + 1) { + fprintf(stderr, "Invalid value for line %d\n", linecount); + continue; + } + if(value > 255) { + fprintf(stderr, "Value %lu for channel %lu is not in range 1..255 in line %d\n", + value, + chan, + linecount); + + continue; + } + + if(*end != '\n') { + fprintf(stderr, "Unecessary characters after value in line %d\n", linecount); + continue; + } + + twinkl_set_value(&msg, chan, value); + } + + free(line); + + twinklsocket_send(twinklsocket, &msg); + + printf("Twinkl paket sent.\n"); + + twinklsocket_close(twinklsocket); + + return 0; +} diff --git a/twinkl b/twinkl new file mode 160000 index 0000000..f3c809e --- /dev/null +++ b/twinkl @@ -0,0 +1 @@ +Subproject commit f3c809e1be4d49e73c52255f1d54abce23370d30 diff --git a/twinklsocket.c b/twinklsocket.c new file mode 100644 index 0000000..04415dc --- /dev/null +++ b/twinklsocket.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "twinklsocket.h" + + +int twinklsocket_open(const char *host, const char *port) { + int sockfd; + struct addrinfo hints, *servinfo, *p; + int result; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + result = getaddrinfo(host, port, &hints, &servinfo); + if(result != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(result)); + exit(1); + } + + // loop through all the results and make a socket + for(p = servinfo; p != NULL; p = p->ai_next) { + sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if(sockfd != -1) { + break; + } + } + + if (p == NULL) { + fprintf(stderr, "failed to create socket\n"); + exit(1); + } + + result = connect(sockfd, p->ai_addr, p->ai_addrlen); + if(result != 0) { + perror("connect"); + exit(1); + } + + freeaddrinfo(servinfo); + + return sockfd; +} + +void twinklsocket_send(int sockfd, const struct twinkl_message *message) { + int numbytes; + + numbytes = send(sockfd, message, sizeof(struct twinkl_message), 0); + if (numbytes == -1) { + perror("sendto"); + exit(1); + } +} + +void twinklsocket_close(int sockfd) { + close(sockfd); +}