Initial commit of bcast, has terminal interface and x11 interface stub
commit
af41084368
|
@ -0,0 +1,42 @@
|
||||||
|
OUT = bcast
|
||||||
|
PREFIX=./
|
||||||
|
OBJS = main.o net.o common.o
|
||||||
|
CON_OBJS = con/console.o
|
||||||
|
CC = gcc
|
||||||
|
DEBUG = -g
|
||||||
|
CFLAGS = -Wall -c $(DEBUG)
|
||||||
|
LFLAGS = -Wall $(DEBUG)
|
||||||
|
X11_OBJS = x11/x11.o
|
||||||
|
X11_LFLAGS = -L/usr/X11R6/lib -lX11
|
||||||
|
|
||||||
|
$(OUT): $(CON_OBJS) $(OBJS)
|
||||||
|
$(CC) $(OBJS) $(CON_OBJS) $(LFLAGS) -o $(OUT)
|
||||||
|
|
||||||
|
ccast: $(OBJS) $(CON_OBJS)
|
||||||
|
$(CC) $(OBJS) $(CON_OBJS) $(LFLAGS) -o ccast
|
||||||
|
|
||||||
|
xcast: $(OBJS) $(X11_OBJS)
|
||||||
|
$(CC) $(OBJS) $(X11_OBJS) $(LFLAGS) $(X11_LFLAGS) -o xcast
|
||||||
|
|
||||||
|
all: bcast ccast xcast
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(OBJS) $(CON_OBJS) $(X11_OBJS) ccast xcast $(OUT)
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp $(OUT) $(PREFIX)/$(OUT)
|
||||||
|
|
||||||
|
net.o: net.c net.h macros.h
|
||||||
|
$(CC) $(CFLAGS) -c net.c
|
||||||
|
|
||||||
|
main.o: main.c net.h common.h con/console.h macros.h ui_common.h
|
||||||
|
$(CC) $(CFLAGS) -c main.c
|
||||||
|
|
||||||
|
common.o: common.c common.h macros.h
|
||||||
|
$(CC) $(CFLAGS) -c common.c
|
||||||
|
|
||||||
|
console.o: con/console.c con/console.h ui_common.h
|
||||||
|
$(CC) $(CFLAGS) -c con/console.c
|
||||||
|
|
||||||
|
x11.o: x11/x11.c x11/x11.h ui_common.h x11/x11_assets.h
|
||||||
|
$(CC) $(CFLAGS) -c x11/x11.c
|
|
@ -0,0 +1,145 @@
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
char * strndup (const char *s, size_t n) {
|
||||||
|
char *result;
|
||||||
|
size_t len = strlen (s);
|
||||||
|
|
||||||
|
if (n < len)
|
||||||
|
len = n;
|
||||||
|
|
||||||
|
result = (char *) malloc (len + 1);
|
||||||
|
if (!result)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result[len] = '\0';
|
||||||
|
return (char *) memcpy (result, s, len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void buildCommands() {
|
||||||
|
//char** commands = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//void addCommand(const char *command_string, void(*function)()) {
|
||||||
|
void addCommand(const char *command_string, void(*function)) {
|
||||||
|
int hash = generateHash(command_string, COMMAND_HASH_SIZE);
|
||||||
|
printf("command '%s' added with hash %d\n", command_string, hash);
|
||||||
|
commands_table[hash] = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **getCommand(const char* string) {
|
||||||
|
char** command_array = NULL;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = 1;
|
||||||
|
char last_pos = 0;
|
||||||
|
|
||||||
|
char current_char = string[i];
|
||||||
|
short done = 0;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
if (current_char == ' ') {
|
||||||
|
command_array = realloc(command_array, sizeof(char*)*j+1);
|
||||||
|
if (command_array == NULL) {
|
||||||
|
printf("ERROR, couldn't allocate memory for command_array\n");
|
||||||
|
}
|
||||||
|
command_array[j] = strndup(string+last_pos+1, i-last_pos-1);
|
||||||
|
last_pos = i;
|
||||||
|
j++;
|
||||||
|
} else if (current_char == '\n') {
|
||||||
|
command_array = realloc(command_array, sizeof(char*)*j+1);
|
||||||
|
if (command_array == NULL) {
|
||||||
|
printf("ERROR, couldn't allocate memory for command_array\n");
|
||||||
|
}
|
||||||
|
command_array[j] = strndup(string+last_pos+1, i-last_pos-1);
|
||||||
|
last_pos = i;
|
||||||
|
done = 1;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
current_char = string[i];
|
||||||
|
}
|
||||||
|
command_array[0] = (void*)(intptr_t)(j-1);
|
||||||
|
return command_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeCommand(char **command_array) {
|
||||||
|
//printf("res[0] = %d\n", command_array[0]);
|
||||||
|
int j;
|
||||||
|
for (j = 1; j < (intptr_t)command_array[0]+1; j++) {
|
||||||
|
//printf("res[%d] = %s\n", j, command_array[j]);
|
||||||
|
free(command_array[j]);
|
||||||
|
}
|
||||||
|
free(command_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
int generateHash(const char* string, int table_size) {
|
||||||
|
int i, sum;
|
||||||
|
size_t string_length = strlen(string);
|
||||||
|
for (sum=0, i=0; i < string_length; i++) {
|
||||||
|
sum += string[i];
|
||||||
|
}
|
||||||
|
return sum % table_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConfig(const char* variable, const char* value) {
|
||||||
|
if (variable && value) {
|
||||||
|
int hash = generateHash(variable, CONFIG_HASH_SIZE);
|
||||||
|
//printf("\n%s's hash is %d\n", variable, hash);
|
||||||
|
config[hash] = realloc(config[hash], strlen(value));
|
||||||
|
strcpy(config[hash], value);
|
||||||
|
|
||||||
|
config_name[hash] = realloc(config_name[hash], strlen(variable));
|
||||||
|
strcpy(config_name[hash], variable);
|
||||||
|
|
||||||
|
printf("%s(%d) set to %s\n", config_name[hash], hash, config[hash]);
|
||||||
|
//printf("%s's value: %s\n", variable, config[hash]);
|
||||||
|
} else {
|
||||||
|
printf("usage: %s", SET_SYNTAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeConfig() {
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0;i < CONFIG_HASH_SIZE;i++) {
|
||||||
|
if (config[i]) {
|
||||||
|
free(config[i]);
|
||||||
|
free(config_name[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addHelp(const char* variable, const char* value) {
|
||||||
|
int hash = generateHash(variable, COMMAND_HASH_SIZE);
|
||||||
|
help[hash] = realloc(help[hash], strlen(value));
|
||||||
|
strcpy(help[hash], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeHelp() {
|
||||||
|
int i;
|
||||||
|
for (i = 0;i < COMMAND_HASH_SIZE;i++) {
|
||||||
|
if (help[i]) {
|
||||||
|
free(help[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSyntax(const char* variable, const char* value) {
|
||||||
|
int hash = generateHash(variable, COMMAND_HASH_SIZE);
|
||||||
|
syntax[hash] = realloc(syntax[hash], strlen(value));
|
||||||
|
strcpy(syntax[hash], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeSyntax() {
|
||||||
|
int i;
|
||||||
|
for (i = 0;i < COMMAND_HASH_SIZE;i++) {
|
||||||
|
if (syntax[i]) {
|
||||||
|
free(syntax[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void quitProgram() {
|
||||||
|
is_running = 0;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Common
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <stdint.h> // for intptr_t http://stackoverflow.com/questions/5701450/getting-the-warning-cast-to-pointer-from-integer-of-different-size-from-the-fo#5703367
|
||||||
|
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
char * strndup (const char *s, size_t n);
|
||||||
|
#endif
|
||||||
|
/* etc */
|
||||||
|
|
||||||
|
char *start_message[3];
|
||||||
|
|
||||||
|
char* command_array;
|
||||||
|
|
||||||
|
char** getCommand(const char* string);
|
||||||
|
void freeCommand(char **command_array);
|
||||||
|
|
||||||
|
int generateHash(const char* string, int table_size);
|
||||||
|
//void addCommand(const char *command_string, void(*function)(const void*, const void*, const void*));
|
||||||
|
//void addCommand(const char *command_string, void(*function)());
|
||||||
|
void addCommand(const char *command_string, void(*function));
|
||||||
|
//void (*commands_table[64]) (const void*, const void*);
|
||||||
|
void (*commands_table[COMMAND_HASH_SIZE]) ();
|
||||||
|
//void(*function)(const void*, const void*, const void*) **commands[64]; // array of command strings, e.g., "quit", "save", etc.
|
||||||
|
//int *commands_table; // array of command hashes (integers).
|
||||||
|
int commands_length; // total of commands available
|
||||||
|
int hash_size; // err, change this.
|
||||||
|
|
||||||
|
char *help[COMMAND_HASH_SIZE];
|
||||||
|
char *syntax[COMMAND_HASH_SIZE];
|
||||||
|
|
||||||
|
char *config_name[CONFIG_HASH_SIZE];
|
||||||
|
char (*config[CONFIG_HASH_SIZE]);
|
||||||
|
void setConfig(const char* variable, const char* value);
|
||||||
|
|
||||||
|
int is_running;
|
||||||
|
void quitProgram();
|
||||||
|
|
||||||
|
|
||||||
|
void addHelp(const char* variable, const char* value);
|
||||||
|
void addSyntax(const char* variable, const char* value);
|
||||||
|
void freeHelp();
|
||||||
|
void freeSyntax();
|
||||||
|
void freeConfig();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int length;
|
||||||
|
char *arg;
|
||||||
|
} t_command;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,213 @@
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
|
int initInterface() {
|
||||||
|
setAttribute(GREEN);
|
||||||
|
setAttribute(DIM);
|
||||||
|
printf("%s", START_MESSAGE);
|
||||||
|
clearAttributes();
|
||||||
|
|
||||||
|
showInterfaces();
|
||||||
|
|
||||||
|
showHelp(NULL);
|
||||||
|
setAttribute(MAGENTA);
|
||||||
|
setAttribute(UNDERSCORE);
|
||||||
|
printf("\n--ready--");
|
||||||
|
clearAttributes();
|
||||||
|
|
||||||
|
interface_fd = STDIN;
|
||||||
|
FD_SET(interface_fd, &master_fds);
|
||||||
|
max_fd = interface_fd;
|
||||||
|
|
||||||
|
showPrompt();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closeInterface() {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleInterface() {
|
||||||
|
// TODO: change to while loop :S
|
||||||
|
if (read(interface_fd, data_buffer, 2048) < 0) {
|
||||||
|
perror("couldn't read() STDIN");
|
||||||
|
} else {
|
||||||
|
if (data_buffer[0] == '/') { // denotes command
|
||||||
|
char **command = getCommand(data_buffer);
|
||||||
|
int command_hash = generateHash(command[1], COMMAND_HASH_SIZE);
|
||||||
|
if (!commands_table[command_hash]) {
|
||||||
|
clearLine();
|
||||||
|
setAttribute(YELLOW);
|
||||||
|
printf("%s '%s'", UNKNOWN_MESSAGE, command[1]);
|
||||||
|
clearAttributes();
|
||||||
|
} else {
|
||||||
|
if ((intptr_t)command[0] == 1) { // if only /command
|
||||||
|
(*commands_table[command_hash])(NULL);
|
||||||
|
} else if ((intptr_t)command[0] == 2) { // if 1 args
|
||||||
|
(*commands_table[command_hash])(command[2]);
|
||||||
|
} else if ((intptr_t)command[0] == 3) { // if 2 args
|
||||||
|
(*commands_table[command_hash])(command[2], command[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("\nhash of command %s: %d\n", command[1], generateHash(command[1], 64));
|
||||||
|
freeCommand(command);
|
||||||
|
showPrompt();
|
||||||
|
} else if (data_buffer[0] == '\n') { // return
|
||||||
|
fputs("\033[A\033[2K",stdout);
|
||||||
|
rewind(stdout);
|
||||||
|
ftruncate(1,0);
|
||||||
|
//fputs("\033[A",stdout);
|
||||||
|
fputs("\033[32m",stdout);
|
||||||
|
printf("> ");
|
||||||
|
fputs("\033[0m",stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
} else {
|
||||||
|
if (is_listening) {
|
||||||
|
int i = 0;
|
||||||
|
int done = 0;
|
||||||
|
while (!done) {
|
||||||
|
if (data_buffer[i++] == '\n')
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
char message[i-1];
|
||||||
|
strncpy(message, data_buffer, i-1); // cut the \n
|
||||||
|
message[i-1] = '\0';
|
||||||
|
|
||||||
|
clearLine();
|
||||||
|
sendOpen(message);
|
||||||
|
showPrompt();
|
||||||
|
// sendMulticast(send_socket, &group_socket, data_buffer, strlen(data_buffer));
|
||||||
|
/* fputs("\033[A\033[2K",stdout);
|
||||||
|
rewind(stdout);
|
||||||
|
ftruncate(1,0);
|
||||||
|
fputs("\033[32m",stdout);
|
||||||
|
printf("> ");
|
||||||
|
fputs("\033[0m",stdout);
|
||||||
|
fflush(stdout);*/
|
||||||
|
} else {
|
||||||
|
setAttribute(RED);
|
||||||
|
printf("not listening");
|
||||||
|
clearAttributes();
|
||||||
|
showPrompt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleInput(const char *data_buffer) {
|
||||||
|
fputs("\033[1A", stdout);
|
||||||
|
printf("\n");
|
||||||
|
fputs("\033[2K",stdout); // move up and clear
|
||||||
|
rewind(stdout);
|
||||||
|
ftruncate(1,0);
|
||||||
|
receiveOpen(data_buffer, DATAGRAM_SIZE);
|
||||||
|
// fputs("\033[1B",stdout); // move cursor back down
|
||||||
|
// fputs("\033[u", stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
showPrompt();
|
||||||
|
/*fputs("\033[2K",stdout);
|
||||||
|
rewind(stdout);
|
||||||
|
ftruncate(1,0);
|
||||||
|
printf("data_in: %s", data_buffer);
|
||||||
|
showPrompt();*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showHelp(const char *value) {
|
||||||
|
setAttribute(MAGENTA);
|
||||||
|
setAttribute(UNDERSCORE);
|
||||||
|
printf("--help--\n");
|
||||||
|
clearAttributes();
|
||||||
|
if (value) {
|
||||||
|
int hash = generateHash(value, COMMAND_HASH_SIZE);
|
||||||
|
if (help[hash]) {
|
||||||
|
setAttribute(CYAN);
|
||||||
|
printf("%s", help[hash]);
|
||||||
|
if (syntax[hash]) {
|
||||||
|
printf("\nusage: %s", syntax[hash]);
|
||||||
|
}
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAttribute(CYAN);
|
||||||
|
printf("%s", HELP_MESSAGE);
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showVariables() {
|
||||||
|
setAttribute(MAGENTA);
|
||||||
|
setAttribute(UNDERSCORE);
|
||||||
|
printf("--variables--\n");
|
||||||
|
clearAttributes();
|
||||||
|
int i;
|
||||||
|
for (i = 0;i < CONFIG_HASH_SIZE;i++) {
|
||||||
|
if (config[i]) {
|
||||||
|
setAttribute(GREEN);
|
||||||
|
printf("%s(%d): ", config_name[i], i);
|
||||||
|
clearAttributes();
|
||||||
|
printf("%s\n", config[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showInterfaces() {
|
||||||
|
int i;
|
||||||
|
fputs("\033[4m\033[35m", stdout);
|
||||||
|
printf("--%d interfaces detected--\n", interfaces);
|
||||||
|
fputs("\033[0m",stdout);
|
||||||
|
fputs("\033[32m", stdout);
|
||||||
|
for (i = 0; i < interfaces; i++) {
|
||||||
|
if (ip_list[i]) {
|
||||||
|
printf("%s: %s\n", dev_list[i], ip_list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fputs("\033[0m",stdout);
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAttribute(const int attribute) {
|
||||||
|
switch(attribute) {
|
||||||
|
case RED:
|
||||||
|
fputs("\033[31m",stdout);
|
||||||
|
break;
|
||||||
|
case YELLOW:
|
||||||
|
fputs("\033[33m",stdout);
|
||||||
|
break;
|
||||||
|
case GREEN:
|
||||||
|
fputs("\033[32m", stdout);
|
||||||
|
break;
|
||||||
|
case CYAN:
|
||||||
|
fputs("\033[36m", stdout);
|
||||||
|
break;
|
||||||
|
case MAGENTA:
|
||||||
|
fputs("\033[35m", stdout);
|
||||||
|
break;
|
||||||
|
case UNDERSCORE:
|
||||||
|
fputs("\033[4m", stdout);
|
||||||
|
break;
|
||||||
|
case DIM:
|
||||||
|
fputs("\033[2m", stdout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearAttributes() {
|
||||||
|
fputs("\033[0m", stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showPrompt() {
|
||||||
|
fputs("\033[32m",stdout);
|
||||||
|
printf("\n> ");
|
||||||
|
fputs("\033[0m",stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLine() {
|
||||||
|
fputs("\033[A\033[2K",stdout);
|
||||||
|
rewind(stdout);
|
||||||
|
ftruncate(1,0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef CONSOLE_H
|
||||||
|
#define CONSOLE_H
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <unistd.h> // ftruncate
|
||||||
|
|
||||||
|
#include "../ui_common.h"
|
||||||
|
#include "../common.h"
|
||||||
|
#include "../macros.h"
|
||||||
|
#include "../net.h"
|
||||||
|
|
||||||
|
#define RED 31
|
||||||
|
#define GREEN 32
|
||||||
|
#define YELLOW 33
|
||||||
|
#define CYAN 34
|
||||||
|
#define MAGENTA 35
|
||||||
|
|
||||||
|
#define UNDERSCORE 4
|
||||||
|
#define DIM 2
|
||||||
|
|
||||||
|
/* ui */
|
||||||
|
void showHelp(const char *value);
|
||||||
|
|
||||||
|
void showInterfaces();
|
||||||
|
void showVariables();
|
||||||
|
void showPrompt();
|
||||||
|
void clearLine();
|
||||||
|
|
||||||
|
void setAttribute(const int);
|
||||||
|
void clearAttributes();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef MACROS_H
|
||||||
|
#define MACROS_H
|
||||||
|
|
||||||
|
#define START_MESSAGE " ______ _______ _______ _______ _______\n |_____] | |_____| |______ | \n |_____] |_____ | | ______| |\n\n"
|
||||||
|
|
||||||
|
/* strings, foo' */
|
||||||
|
#define QUIT_COMMAND "quit"
|
||||||
|
#define QUIT_MESSAGE "さよなら!"
|
||||||
|
#define QUIT_HELP "shuts down running sockets and quits the program"
|
||||||
|
|
||||||
|
#define SET_COMMAND "set"
|
||||||
|
#define SET_MESSAGE "variable: "
|
||||||
|
#define SET_HELP "sets a variable to a value"
|
||||||
|
#define SET_SYNTAX "/set variable value"
|
||||||
|
|
||||||
|
#define LIST_COMMAND "list"
|
||||||
|
#define LIST_HELP "lists all variables and their values\nuse /set to change a variable"
|
||||||
|
|
||||||
|
#define START_COMMAND "start"
|
||||||
|
#define START_HELP "starts either listen or send if specified, otherwise starts both"
|
||||||
|
#define START_SYNTAX "/start listen|send"
|
||||||
|
#define START_LISTEN_COMMAND "listen"
|
||||||
|
#define START_SEND_COMMAND "send"
|
||||||
|
|
||||||
|
#define STOP_COMMAND "stop"
|
||||||
|
#define STOP_HELP "stops either listen or send if specified, otherwise stops both"
|
||||||
|
#define STOP_SYNTAX "/stop {listen|send}"
|
||||||
|
#define STOP_LISTEN_COMMAND "listen"
|
||||||
|
#define STOP_SEND_COMMAND "send"
|
||||||
|
|
||||||
|
#define RESTART_COMMAND "restart"
|
||||||
|
#define RESTART_HELP "restarts listen and/or send if either are running"
|
||||||
|
#define RESTART_SYNTAX "/restart {listen|send}"
|
||||||
|
#define RESTART_LISTEN_COMMAND "listen"
|
||||||
|
#define RESTART_SEND_COMMAND "send"
|
||||||
|
|
||||||
|
#define HELP_COMMAND "help"
|
||||||
|
#define HELP_MESSAGE "type a message and hit return to send\npreface commands with '/'\navailable commands: help, start, stop, restart, set, list, quit"
|
||||||
|
#define HELP_HELP "the help command, obv."
|
||||||
|
#define HELP_SYNTAX "/help {command}"
|
||||||
|
|
||||||
|
#define UNKNOWN_MESSAGE "unknown command"
|
||||||
|
|
||||||
|
/* ints, foo*2 */
|
||||||
|
|
||||||
|
#define STDIN 0
|
||||||
|
#define DATAGRAM_SIZE 512
|
||||||
|
#define COMMAND_HASH_SIZE 64
|
||||||
|
#define CONFIG_HASH_SIZE 64
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include "macros.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "con/console.h"
|
||||||
|
#include "ui_common.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define STDIN 0
|
||||||
|
#define DATAGRAM_SIZE 512
|
||||||
|
|
||||||
|
#define QUIT_STRING "quit"
|
||||||
|
#define QUIT_MESSAGE "さよなら!"
|
||||||
|
|
||||||
|
#define NICK_STRING "nick"
|
||||||
|
#define NICK_MESSAGE "nick set to"
|
||||||
|
#define NICK_SYNTAX "/nick new_nickname"
|
||||||
|
|
||||||
|
#define SET_STRING "set"
|
||||||
|
|
||||||
|
#define SET_IP_STRING "ip"
|
||||||
|
#define SET_IP_MESSAGE "(re)start send/listen sockets to use new IP"
|
||||||
|
#define SET_PORT_STRING "port"
|
||||||
|
|
||||||
|
#define START_STRING "start"
|
||||||
|
#define START_SYNTAX "/start listen|send"
|
||||||
|
#define START_LISTEN "listen"
|
||||||
|
#define START_LISTEN_MESSAGE "--starting listen--"
|
||||||
|
#define START_SEND "send"
|
||||||
|
#define START_SEND_MESSAGE "--starting send--"
|
||||||
|
|
||||||
|
#define STOP_STRING "stop"
|
||||||
|
#define STOP_LISTEN "listen"
|
||||||
|
#define STOP_LISTEN_MESSAGE "--stopping listen--"
|
||||||
|
#define STOP_SEND "send"
|
||||||
|
#define STOP_SEND_MESSAGE "--stopping send--"
|
||||||
|
|
||||||
|
#define RESTART_STRING "restart"
|
||||||
|
#define RESTART_MESSAGE "--restarting sockets--"
|
||||||
|
|
||||||
|
#define HELP_STRING "help"
|
||||||
|
|
||||||
|
#define UNKNOWN_CMD_MESSAGE "unknown command"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char data_buffer[2047];
|
||||||
|
|
||||||
|
FD_ZERO(&master_fds);
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
|
||||||
|
getInterfaces();
|
||||||
|
initNetwork();
|
||||||
|
|
||||||
|
addCommand(QUIT_COMMAND, quitProgram);
|
||||||
|
addCommand(HELP_COMMAND, showHelp);
|
||||||
|
addCommand(SET_COMMAND, setConfig);
|
||||||
|
addCommand(LIST_COMMAND, showVariables);
|
||||||
|
addCommand(RESTART_COMMAND, restartSockets);
|
||||||
|
addCommand(START_COMMAND, startSockets);
|
||||||
|
addCommand(STOP_COMMAND, stopSockets);
|
||||||
|
|
||||||
|
|
||||||
|
addCommand("open", sendOpen);
|
||||||
|
|
||||||
|
addHelp(SET_COMMAND, SET_HELP);
|
||||||
|
addSyntax(SET_COMMAND, SET_SYNTAX);
|
||||||
|
addHelp(LIST_COMMAND, LIST_HELP);
|
||||||
|
addHelp(START_COMMAND, START_HELP);
|
||||||
|
addSyntax(START_COMMAND, START_SYNTAX);
|
||||||
|
addHelp(STOP_COMMAND, STOP_HELP);
|
||||||
|
addSyntax(STOP_COMMAND, STOP_SYNTAX);
|
||||||
|
addHelp(RESTART_COMMAND, RESTART_HELP);
|
||||||
|
addSyntax(RESTART_COMMAND, RESTART_SYNTAX);
|
||||||
|
addHelp(QUIT_COMMAND, QUIT_HELP);
|
||||||
|
addHelp(HELP_COMMAND, HELP_HELP);
|
||||||
|
addSyntax(HELP_COMMAND, HELP_SYNTAX);
|
||||||
|
|
||||||
|
if (initInterface() == 0) {
|
||||||
|
is_running = 1;
|
||||||
|
} else {
|
||||||
|
printf("error, couldn't start interface...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while(is_running) {
|
||||||
|
//for(;;) {
|
||||||
|
read_fds = master_fds;
|
||||||
|
if (select(max_fd+1, &read_fds, NULL, NULL, NULL) == -1) {
|
||||||
|
perror("select");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i <= max_fd; i++) {
|
||||||
|
if (FD_ISSET(i, &read_fds)) {
|
||||||
|
if (i == interface_fd) {
|
||||||
|
handleInterface();
|
||||||
|
} else if (i == listen_socket) {
|
||||||
|
if (recv(listen_socket, data_buffer, DATAGRAM_SIZE, 0) < 0) {
|
||||||
|
perror("couldn't read() listen_socket");
|
||||||
|
} else {
|
||||||
|
handleInput(data_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeInterface();
|
||||||
|
//freeCommands();
|
||||||
|
stopSockets(NULL);
|
||||||
|
freeInterfaces();
|
||||||
|
freeHelp();
|
||||||
|
freeSyntax();
|
||||||
|
freeConfig();
|
||||||
|
setAttribute(GREEN);
|
||||||
|
printf("%s\n", QUIT_MESSAGE);
|
||||||
|
clearAttributes();
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,437 @@
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
int initNetwork() {
|
||||||
|
#if defined(WIN32)
|
||||||
|
WORD wVersionRequested;
|
||||||
|
WSADATA wsaData;
|
||||||
|
int err;
|
||||||
|
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
|
||||||
|
wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
err = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
if (err != 0) {
|
||||||
|
/* Tell the user that we could not find a usable */
|
||||||
|
/* Winsock DLL. */
|
||||||
|
printf("WSAStartup failed with error: %d\n", err);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setConfig("port", "7332");
|
||||||
|
|
||||||
|
char *hostname[15];
|
||||||
|
//char hostname;
|
||||||
|
gethostname(&hostname, 16);
|
||||||
|
|
||||||
|
char *username = getenv("USER");
|
||||||
|
|
||||||
|
size_t nick_length = strlen(hostname)+strlen(username)+1;
|
||||||
|
char nick[nick_length];
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
while(j<strlen(username)) {
|
||||||
|
nick[i++] = username[j++];
|
||||||
|
}
|
||||||
|
nick[i++] = '@';
|
||||||
|
j = 0;
|
||||||
|
while(j<strlen(hostname)) {
|
||||||
|
nick[i++] = hostname[j++];
|
||||||
|
}
|
||||||
|
nick[i] = '\0';
|
||||||
|
|
||||||
|
setConfig("nick", nick);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int openListenSocket() {
|
||||||
|
setAttribute(MAGENTA);
|
||||||
|
setAttribute(UNDERSCORE);
|
||||||
|
printf("--openListenSocket--\n");
|
||||||
|
clearAttributes();
|
||||||
|
int ip_hash = generateHash("ip", CONFIG_HASH_SIZE);
|
||||||
|
int port_hash = generateHash("port", CONFIG_HASH_SIZE);
|
||||||
|
setAttribute(GREEN);
|
||||||
|
printf("IP: %s\n", config[ip_hash]);
|
||||||
|
printf("port: %s\n", config[port_hash]);
|
||||||
|
clearAttributes();
|
||||||
|
printf("open: ");
|
||||||
|
listen_socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (listen_socket < 0) {
|
||||||
|
perror("error");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* printf("non-blocking set: ");
|
||||||
|
if (fcntl(listen_socket, F_SETFL, O_NONBLOCK)) {
|
||||||
|
printf("success\n");
|
||||||
|
} else {
|
||||||
|
perror("fcntl() error");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
printf("SO_REUSEADDR set: ");
|
||||||
|
if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0) {
|
||||||
|
perror("error");
|
||||||
|
return -2;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_group_socket_set) {
|
||||||
|
memset((char *) &group_socket, 0, sizeof(group_socket));
|
||||||
|
group_socket.sin_family = AF_INET;
|
||||||
|
//group_socket.sin_port = htons(7332);
|
||||||
|
group_socket.sin_port = htons((unsigned short)strtoul(config[port_hash], NULL, 0));
|
||||||
|
group_socket.sin_addr.s_addr = inet_addr("226.1.1.1");
|
||||||
|
is_group_socket_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("bind: ");
|
||||||
|
if (bind(listen_socket, (struct sockaddr*)&group_socket, sizeof(group_socket))) {
|
||||||
|
perror("error");
|
||||||
|
return -3;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
|
||||||
|
group.imr_interface.s_addr = inet_addr(config[ip_hash]);
|
||||||
|
//group.imr_interface.s_addr = inet_addr("192.168.182.51");
|
||||||
|
|
||||||
|
printf("IP_ADD_MEMBERSHIP: ");
|
||||||
|
if (setsockopt(listen_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0) {
|
||||||
|
perror("error");
|
||||||
|
return -4;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move this
|
||||||
|
is_listening = 1;
|
||||||
|
/* add to master_fds? */
|
||||||
|
listen_tv.tv_sec=0;
|
||||||
|
listen_tv.tv_usec=0;
|
||||||
|
//FD_ZERO(&master_fds);
|
||||||
|
FD_SET(listen_socket, &master_fds);
|
||||||
|
max_fd = listen_socket;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
int closeListenSocket() {
|
||||||
|
max_fd--;
|
||||||
|
close(listen_socket);
|
||||||
|
is_listening = 0;
|
||||||
|
printf("closed listen_socket\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int openSendSocket() {
|
||||||
|
setAttribute(MAGENTA);
|
||||||
|
setAttribute(UNDERSCORE);
|
||||||
|
printf("--openSendSocket--\n");
|
||||||
|
clearAttributes();
|
||||||
|
int ip_hash = generateHash("ip", CONFIG_HASH_SIZE);
|
||||||
|
int port_hash = generateHash("port", CONFIG_HASH_SIZE);
|
||||||
|
setAttribute(GREEN);
|
||||||
|
printf("IP: %s\n", config[ip_hash]);
|
||||||
|
printf("port: %s\n", config[port_hash]);
|
||||||
|
clearAttributes();
|
||||||
|
printf("open: ");
|
||||||
|
send_socket = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (send_socket < 0) {
|
||||||
|
perror("error");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: doesn't actually disable? :S
|
||||||
|
printf("disable loopback: ");
|
||||||
|
char loopback_char = 0;
|
||||||
|
if (setsockopt(send_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopback_char, sizeof(loopback_char)) < 0) {
|
||||||
|
perror("error");
|
||||||
|
return -2;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
local_interface.s_addr = inet_addr(config[ip_hash]);
|
||||||
|
//local_interface.s_addr = inet_addr("192.168.182.51");
|
||||||
|
printf("local_interface set (%s): ", inet_ntoa(local_interface));
|
||||||
|
if (setsockopt(send_socket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_interface, sizeof(local_interface)) < 0) {
|
||||||
|
perror("error:");
|
||||||
|
return -3;
|
||||||
|
} else {
|
||||||
|
printf("success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init sockaddr */
|
||||||
|
|
||||||
|
if (!is_group_socket_set) {
|
||||||
|
memset((char *) &group_socket, 0, sizeof(group_socket));
|
||||||
|
group_socket.sin_family = PF_INET;
|
||||||
|
group_socket.sin_addr.s_addr = inet_addr("226.1.1.1");
|
||||||
|
//group_socket.sin_port = htons(7332);
|
||||||
|
group_socket.sin_port = htons((unsigned short)strtoul(config[port_hash], NULL, 0));
|
||||||
|
is_group_socket_set = 1;
|
||||||
|
}
|
||||||
|
is_sending = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closeSendSocket() {
|
||||||
|
close(send_socket);
|
||||||
|
is_sending = 0;
|
||||||
|
printf("closed send_socket\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setIp(const char string[]) {
|
||||||
|
int ip_hash = generateHash("ip", CONFIG_HASH_SIZE);
|
||||||
|
// strcpy(&config[ip_hash], string);
|
||||||
|
setString(config[ip_hash], string);
|
||||||
|
printf("ip: %s", config[ip_hash]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setString(char *destination, const char source[]) {
|
||||||
|
size_t len = strlen(source);
|
||||||
|
size_t i = 0;
|
||||||
|
while (source[i] != '\n' && i < len) {
|
||||||
|
destination[i] = source[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
destination[len] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *stripString(const char string[]) {
|
||||||
|
char *result = malloc(15);
|
||||||
|
size_t len = strlen(string);
|
||||||
|
size_t i = 0;
|
||||||
|
char current_char = string[i];
|
||||||
|
while (current_char != '\n' && current_char != '\0' && i < len) {
|
||||||
|
result[i] = current_char;
|
||||||
|
i++;
|
||||||
|
current_char = string[i];
|
||||||
|
}
|
||||||
|
result[15] = '\0';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void restartSockets(const char *value) {
|
||||||
|
if (value) {
|
||||||
|
if (!strcmp(value, START_LISTEN_COMMAND)) {
|
||||||
|
if (is_listening) {
|
||||||
|
stopListenSocket();
|
||||||
|
startListenSocket();
|
||||||
|
}
|
||||||
|
} else if (!strcmp(value, START_SEND_COMMAND)) {
|
||||||
|
if (is_listening) {
|
||||||
|
stopSendSocket();
|
||||||
|
startSendSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_listening) {
|
||||||
|
stopListenSocket();
|
||||||
|
startListenSocket();
|
||||||
|
}
|
||||||
|
if (is_listening) {
|
||||||
|
stopSendSocket();
|
||||||
|
startSendSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void startSockets(const char *value) {
|
||||||
|
if (value) {
|
||||||
|
if (!strcmp(value, START_LISTEN_COMMAND)) {
|
||||||
|
startListenSocket();
|
||||||
|
} else if (!strcmp(value, START_SEND_COMMAND)) {
|
||||||
|
startSendSocket();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startListenSocket();
|
||||||
|
startSendSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopSockets(const char *value) {
|
||||||
|
if (value) {
|
||||||
|
if (!strcmp(value, STOP_LISTEN_COMMAND)) {
|
||||||
|
stopListenSocket();
|
||||||
|
} else if (!strcmp(value, STOP_SEND_COMMAND)) {
|
||||||
|
stopSendSocket();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stopListenSocket();
|
||||||
|
stopSendSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int startListenSocket() {
|
||||||
|
if (!is_listening) {
|
||||||
|
return (openListenSocket());
|
||||||
|
} else {
|
||||||
|
printf("already listening - 'stop' or 'restart' first\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int stopListenSocket() {
|
||||||
|
if (is_listening) {
|
||||||
|
return (closeListenSocket());
|
||||||
|
} else {
|
||||||
|
printf("already stopped - 'start' first\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int startSendSocket() {
|
||||||
|
if (!is_sending) {
|
||||||
|
return(openSendSocket());
|
||||||
|
} else {
|
||||||
|
printf("already sending - 'stop' or 'restart' first\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int stopSendSocket() {
|
||||||
|
if (is_sending) {
|
||||||
|
return(closeSendSocket());
|
||||||
|
} else {
|
||||||
|
printf("already stopped - 'start' first\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleOpenMessage(const char packet[]) {
|
||||||
|
uint8_t nick_size;
|
||||||
|
//uint8_t message_id;
|
||||||
|
//uint8_t payload_type;
|
||||||
|
uint8_t payload_size;
|
||||||
|
|
||||||
|
int offset = 1; // skip past message_type
|
||||||
|
nick_size = packet[offset++];
|
||||||
|
char nick[nick_size];
|
||||||
|
int j = 0;
|
||||||
|
while(j < nick_size) {
|
||||||
|
nick[j++] = packet[offset++];
|
||||||
|
}
|
||||||
|
//message_id = packet[offset++];
|
||||||
|
offset++;
|
||||||
|
//payload_type = packet[offset++];
|
||||||
|
offset++;
|
||||||
|
payload_size = packet[offset++];
|
||||||
|
char payload[payload_size];
|
||||||
|
j = 0;
|
||||||
|
while(j < payload_size) {
|
||||||
|
payload[j++] = packet[offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: %s", nick, payload);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendOpen(char buffer[]) {
|
||||||
|
int packet_size = 0;
|
||||||
|
|
||||||
|
uint8_t message_type = MESSAGE_OPEN;
|
||||||
|
packet_size++; // for message_type
|
||||||
|
|
||||||
|
int nick_hash = generateHash("nick", CONFIG_HASH_SIZE);
|
||||||
|
uint8_t nick_size = strlen(config[nick_hash])+1; // +1 for \0
|
||||||
|
packet_size++; // for nick_length;
|
||||||
|
packet_size += nick_size; // for nick itself
|
||||||
|
uint8_t message_id = 9;
|
||||||
|
packet_size++; // for message_id
|
||||||
|
uint8_t payload_type = 1; // chat type
|
||||||
|
packet_size++; // for payload type
|
||||||
|
|
||||||
|
// char str[] = "testing 1 2 3";
|
||||||
|
uint8_t buffer_size = strlen(buffer)+1;
|
||||||
|
// uint8_t string_length = strlen(str)+1; // +1 for \0, since strlen sucks
|
||||||
|
packet_size++; // for string_length char
|
||||||
|
packet_size += buffer_size; // for payload itself
|
||||||
|
|
||||||
|
// printf("packet size will be %d\n", packet_size);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int packet_offset = 0;
|
||||||
|
char packet[packet_size];
|
||||||
|
|
||||||
|
packet[packet_offset++] = message_type;
|
||||||
|
packet[packet_offset++] = nick_size;
|
||||||
|
|
||||||
|
while (i < nick_size) {
|
||||||
|
packet[packet_offset++] = config[nick_hash][i++];
|
||||||
|
}
|
||||||
|
packet[packet_offset++] = message_id;
|
||||||
|
packet[packet_offset++] = payload_type;
|
||||||
|
packet[packet_offset++] = buffer_size;
|
||||||
|
i = 0;
|
||||||
|
while (i < buffer_size) {
|
||||||
|
packet[packet_offset++] = buffer[i++];
|
||||||
|
}
|
||||||
|
receiveOpen(packet, DATAGRAM_SIZE);
|
||||||
|
sendMulticast(send_socket, &group_socket, packet, packet_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void receiveOpen(const char packet[], size_t packet_size) {
|
||||||
|
if (packet[0] == MESSAGE_OPEN) {
|
||||||
|
handleOpenMessage(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendMulticast(int send_socket, struct sockaddr_in *group_socket, char data_buffer[], int data_length) {
|
||||||
|
if (sendto(send_socket, data_buffer, data_length, 0, (struct sockaddr*)group_socket, sizeof((*group_socket))) < 0) {
|
||||||
|
perror("sendto error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: interface list & IPs broken on OS X - perhaps due to IPV6 being active?
|
||||||
|
void getInterfaces() {
|
||||||
|
int i;
|
||||||
|
int test_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (test_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ifconf.ifc_buf = (char *) ifreq;
|
||||||
|
|
||||||
|
// Set ifconf's ifc_len to the length of our array of interface ifreqs.
|
||||||
|
ifconf.ifc_len = sizeof ifreq;
|
||||||
|
|
||||||
|
// Populate ifconf.ifc_buf (ifreq) with a list of interface names and addresses.
|
||||||
|
if (ioctl(test_socket, SIOCGIFCONF, &ifconf) == -1)
|
||||||
|
return;
|
||||||
|
// Divide the length of the interface list by the size of each entry.
|
||||||
|
// This gives us the number of interfaces on the system.
|
||||||
|
interfaces = ifconf.ifc_len / sizeof(ifreq[0]);
|
||||||
|
|
||||||
|
for (i = 0; i < interfaces; i++) {
|
||||||
|
char ip[INET_ADDRSTRLEN];
|
||||||
|
struct sockaddr_in *address = (struct sockaddr_in *) &ifreq[i].ifr_addr;
|
||||||
|
|
||||||
|
// Convert the binary IP address into a readable string.
|
||||||
|
if (!inet_ntop(AF_INET, &address->sin_addr, ip, sizeof(ip)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ip_list[i] = malloc(strlen(ip));
|
||||||
|
setString(ip_list[i], ip);
|
||||||
|
printf("%s - %s\n", ifreq[i].ifr_name, ip);
|
||||||
|
dev_list[i] = malloc(strlen(ifreq[i].ifr_name));
|
||||||
|
setString(dev_list[i], ifreq[i].ifr_name);
|
||||||
|
}
|
||||||
|
close(test_socket);
|
||||||
|
setConfig("ip", ip_list[interfaces-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeInterfaces() {
|
||||||
|
int i;
|
||||||
|
for (i = 0;i < interfaces;i++) {
|
||||||
|
if (ip_list[i]) {
|
||||||
|
free(ip_list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Net
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
#ifndef NET_H
|
||||||
|
#define NET_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined (WIN32)
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Ws2tcpip.h>
|
||||||
|
#include <Winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h> //
|
||||||
|
#include <net/if.h> // for ifreq
|
||||||
|
|
||||||
|
#include "common.h" // for config
|
||||||
|
#include "con/console.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MESSAGE_OPEN 0
|
||||||
|
|
||||||
|
struct in_addr local_interface;
|
||||||
|
struct sockaddr_in group_socket;
|
||||||
|
struct ip_mreq group;
|
||||||
|
int listen_socket;
|
||||||
|
int send_socket;
|
||||||
|
|
||||||
|
/* "bools" */
|
||||||
|
int is_listening;
|
||||||
|
int is_sending;
|
||||||
|
int is_group_socket_set;
|
||||||
|
|
||||||
|
/* ifreq */
|
||||||
|
struct ifconf ifconf;
|
||||||
|
struct ifreq ifreq[31];
|
||||||
|
int interfaces;
|
||||||
|
char *ip_list[16];
|
||||||
|
char *dev_list[16];
|
||||||
|
|
||||||
|
/* listen */
|
||||||
|
struct timeval listen_tv;
|
||||||
|
fd_set master_fds;
|
||||||
|
fd_set read_fds;
|
||||||
|
int max_fd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
char data_buffer[512];
|
||||||
|
int data_buffer_length;
|
||||||
|
|
||||||
|
char ip_address[15];
|
||||||
|
char port[15];
|
||||||
|
|
||||||
|
int setIp(const char string[]);
|
||||||
|
|
||||||
|
int initNetwork();
|
||||||
|
|
||||||
|
void getInterfaces(); // same v
|
||||||
|
void freeInterfaces(); // change to int
|
||||||
|
|
||||||
|
void startSockets(const char *value);
|
||||||
|
void stopSockets(const char *value);
|
||||||
|
void restartSockets(const char *value);
|
||||||
|
|
||||||
|
int startSendSocket();
|
||||||
|
int stopSendSocket();
|
||||||
|
int openSendSocket();
|
||||||
|
int closeSendSocket();
|
||||||
|
int startListenSocket();
|
||||||
|
int stopListenSocket();
|
||||||
|
int openListenSocket();
|
||||||
|
int closeListenSocket();
|
||||||
|
int receiveSocket(int send_socket);
|
||||||
|
int checkSocket();
|
||||||
|
int sendMulticast(int send_socket, struct sockaddr_in *group_socket, char data_buffer[], int data_length);
|
||||||
|
void sendOpen();
|
||||||
|
|
||||||
|
void receiveOpen(const char packet[], size_t packet_size);
|
||||||
|
int handleOpenMessage(const char packet[]);
|
||||||
|
|
||||||
|
int setString(char *destination, const char source[]);
|
||||||
|
char *stripString(const char string[]);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
Display::Display() {
|
||||||
|
std::cout << "Display::Display()" << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Display::~Display() {
|
||||||
|
std::cout << "Display::~Display()" << std::endl;
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Display
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
#ifndef DISPLAY_H
|
||||||
|
#define DISPLAY_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Display {
|
||||||
|
// private:
|
||||||
|
public:
|
||||||
|
Display();
|
||||||
|
~Display();
|
||||||
|
// void Begin();
|
||||||
|
// void End();
|
||||||
|
};
|
||||||
|
#endif
|
Binary file not shown.
|
@ -0,0 +1,15 @@
|
||||||
|
#include "Listener.h"
|
||||||
|
|
||||||
|
Listener::Listener(short port_) {
|
||||||
|
this->port = port;
|
||||||
|
std::cout << "Listener::Listener()" << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Listener::~Listener() {
|
||||||
|
std::cout << "Listener::~Listener()" << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
// main loop, so to speak.
|
||||||
|
void Listener::Run() {
|
||||||
|
std::cout << "Listener::Run()" << std::endl;
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Listener
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
#ifndef LISTENER_H
|
||||||
|
#define LISTENER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Listener {
|
||||||
|
private:
|
||||||
|
short port;
|
||||||
|
void Run();
|
||||||
|
public:
|
||||||
|
Listener(short port);
|
||||||
|
~Listener();
|
||||||
|
// void Begin();
|
||||||
|
// void End();
|
||||||
|
};
|
||||||
|
#endif
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
||||||
|
OUT = bcast
|
||||||
|
PREFIX=./
|
||||||
|
OBJS = main.o Listener.o Display.o
|
||||||
|
CXX = g++
|
||||||
|
DEBUG = -g
|
||||||
|
CXXFLAGS = -std=gnu++11 -Wall -c $(DEBUG)
|
||||||
|
LFLAGS = -Wall $(DEBUG)
|
||||||
|
|
||||||
|
$(OUT): $(OBJS)
|
||||||
|
$(CXX) $(OBJS) $(LFLAGS) -o $(OUT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o $(OUT)
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp $(OUT) $(PREFIX)/$(OUT)
|
||||||
|
|
||||||
|
Listener.o: Listener.cpp Listener.h
|
||||||
|
$(CXX) $(CXXFLAGS) -c Listener.cpp
|
||||||
|
|
||||||
|
Display.o: Display.cpp Display.h
|
||||||
|
$(CXX) $(CXXFLAGS) -c Display.cpp
|
||||||
|
|
||||||
|
main.o: main.cpp Listener.h Display.h
|
||||||
|
$(CXX) $(CXXFLAGS) -c main.cpp
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "Listener.h"
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Listener *listener = new Listener(7331);
|
||||||
|
Display *display = new Display();
|
||||||
|
// dia_val_ai->Begin();
|
||||||
|
delete listener;
|
||||||
|
delete display;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,160 @@
|
||||||
|
/* Send Multicast Datagram code example. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct in_addr localInterface;
|
||||||
|
|
||||||
|
struct sockaddr_in groupSock;
|
||||||
|
|
||||||
|
int sd;
|
||||||
|
|
||||||
|
char databuf[1024] = "Multicast test message lol!";
|
||||||
|
|
||||||
|
int datalen = sizeof(databuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char *argv[ ])
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Create a datagram socket on which to send. */
|
||||||
|
|
||||||
|
sd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
if(sd < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Opening datagram socket error");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Opening the datagram socket...OK.\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize the group sockaddr structure with a */
|
||||||
|
|
||||||
|
/* group address of 225.1.1.1 and port 5555. */
|
||||||
|
|
||||||
|
memset((char *) &groupSock, 0, sizeof(groupSock));
|
||||||
|
|
||||||
|
groupSock.sin_family = PF_INET;
|
||||||
|
|
||||||
|
groupSock.sin_addr.s_addr = inet_addr("226.1.1.1");
|
||||||
|
|
||||||
|
groupSock.sin_port = htons(7332);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Disable loopback so you do not receive your own datagrams.
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
char loopch = 0;
|
||||||
|
|
||||||
|
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch)) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Setting IP_MULTICAST_LOOP error");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Disabling the loopback...OK.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Set local interface for outbound multicast datagrams. */
|
||||||
|
|
||||||
|
/* The IP address specified must be associated with a local, */
|
||||||
|
|
||||||
|
/* multicast capable interface. */
|
||||||
|
|
||||||
|
localInterface.s_addr = inet_addr("192.168.182.51");
|
||||||
|
|
||||||
|
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Setting local interface error");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Setting the local interface...OK\n");
|
||||||
|
|
||||||
|
/* Send a message to the multicast group specified by the*/
|
||||||
|
|
||||||
|
/* groupSock sockaddr structure. */
|
||||||
|
|
||||||
|
/*int datalen = 1024;*/
|
||||||
|
|
||||||
|
if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock, sizeof(groupSock)) < 0)
|
||||||
|
|
||||||
|
{perror("Sending datagram message error");}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Sending datagram message...OK\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Try the re-read from the socket if the loopback is not disable
|
||||||
|
|
||||||
|
if(read(sd, databuf, datalen) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Reading datagram message error\n");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("Reading datagram message from client...OK\n");
|
||||||
|
|
||||||
|
printf("The message is: %s\n", databuf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,172 @@
|
||||||
|
|
||||||
|
|
||||||
|
/* Receiver/client multicast Datagram example. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct sockaddr_in localSock;
|
||||||
|
|
||||||
|
struct ip_mreq group;
|
||||||
|
|
||||||
|
int sd;
|
||||||
|
|
||||||
|
int datalen;
|
||||||
|
|
||||||
|
char databuf[1024];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Create a datagram socket on which to receive. */
|
||||||
|
|
||||||
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
if(sd < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Opening datagram socket error");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Opening datagram socket....OK.\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Enable SO_REUSEADDR to allow multiple instances of this */
|
||||||
|
|
||||||
|
/* application to receive copies of the multicast datagrams. */
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
|
||||||
|
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Setting SO_REUSEADDR error");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Setting SO_REUSEADDR...OK.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Bind to the proper port number with the IP address */
|
||||||
|
|
||||||
|
/* specified as INADDR_ANY. */
|
||||||
|
|
||||||
|
memset((char *) &localSock, 0, sizeof(localSock));
|
||||||
|
|
||||||
|
localSock.sin_family = AF_INET;
|
||||||
|
|
||||||
|
localSock.sin_port = htons(7332);
|
||||||
|
|
||||||
|
localSock.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Binding datagram socket error");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Binding datagram socket...OK.\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Join the multicast group 226.1.1.1 on the local 203.106.93.94 */
|
||||||
|
|
||||||
|
/* interface. Note that this IP_ADD_MEMBERSHIP option must be */
|
||||||
|
|
||||||
|
/* called for each local interface over which the multicast */
|
||||||
|
|
||||||
|
/* datagrams are to be received. */
|
||||||
|
|
||||||
|
group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
|
||||||
|
|
||||||
|
group.imr_interface.s_addr = inet_addr("192.168.182.51");
|
||||||
|
|
||||||
|
if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Adding multicast group error");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
printf("Adding multicast group...OK.\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Read from the socket. */
|
||||||
|
|
||||||
|
datalen = sizeof(databuf);
|
||||||
|
|
||||||
|
if(read(sd, databuf, datalen) < 0)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
perror("Reading datagram message error");
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("Reading datagram message...OK.\n");
|
||||||
|
|
||||||
|
printf("The message from multicast server is: \"%s\"\n", databuf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef UI_COMMON_H
|
||||||
|
#define UI_COMMON_H
|
||||||
|
|
||||||
|
int initInterface();
|
||||||
|
int closeInterface();
|
||||||
|
|
||||||
|
int interface_fd;
|
||||||
|
|
||||||
|
int handleInterface();
|
||||||
|
int handleInput(const char *data_buffer);
|
||||||
|
|
||||||
|
/* remove */
|
||||||
|
void showHelp(const char *value);
|
||||||
|
void showVariables();
|
||||||
|
|
||||||
|
void showPrompt();
|
||||||
|
|
||||||
|
void setAttribute(const int);
|
||||||
|
void clearAttributes();
|
||||||
|
|
||||||
|
//void clearLine();
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,413 @@
|
||||||
|
#include "x11.h"
|
||||||
|
|
||||||
|
void testFunc(){}
|
||||||
|
|
||||||
|
void drawLogo() {
|
||||||
|
// char tmp[] = "#008800";
|
||||||
|
// XParseColor(display, colormap, tmp, &tmp_color);
|
||||||
|
// XAllocColor(display, colormap, &tmp_color);
|
||||||
|
// XSetForeground(display, gc, tmp_color.pixel);
|
||||||
|
//XSetForeground(display, gc, 12812818);
|
||||||
|
srand(time(NULL));
|
||||||
|
XSetForeground(display, gc, rand());
|
||||||
|
|
||||||
|
XDrawArc(display, window, gc, -26, -24, 72, 48, (260*64), (90*64));
|
||||||
|
XDrawArc(display, window, gc, -28, -26, 76, 52, (260*64), (90*64));
|
||||||
|
XDrawArc(display, window, gc, -32, -30, 80, 56, (260*64), (90*64));
|
||||||
|
XDrawString(display, window, gc, 4, 13, "bcast", 5);
|
||||||
|
XDrawString(display, window, gc, 4, 13, "bcast", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int initInterface() {
|
||||||
|
x_logo.chars = START_MESSAGE;
|
||||||
|
x_logo.nchars = 60;
|
||||||
|
x_logo.delta = 10;
|
||||||
|
|
||||||
|
display = XOpenDisplay(NULL);
|
||||||
|
screen = DefaultScreen(display);
|
||||||
|
int black = BlackPixel(display, screen);
|
||||||
|
int white = WhitePixel(display, screen);
|
||||||
|
|
||||||
|
window = XCreateSimpleWindow(display, RootWindow(display, 0), 1, 1,
|
||||||
|
240, 320, 0, white, black);
|
||||||
|
//window = XCreateSimpleWindow(display, RootWindow(display, 0), 1, 1, 256, 256, 0, BlackPixel (display, 0), BlackPixel(display, 0));
|
||||||
|
XSetStandardProperties(display, window, "bcast", "bcast", None, NULL, 0, NULL);
|
||||||
|
XMapWindow(display, window);
|
||||||
|
|
||||||
|
gc = XCreateGC(display, window, 0, 0);
|
||||||
|
XSetForeground(display, gc, WhitePixel(display, screen));
|
||||||
|
XSetBackground(display, gc, BlackPixel(display, screen));
|
||||||
|
|
||||||
|
XSelectInput(display, window,
|
||||||
|
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask
|
||||||
|
| ButtonReleaseMask | StructureNotifyMask
|
||||||
|
);
|
||||||
|
|
||||||
|
/* set our colormap */
|
||||||
|
// int i;
|
||||||
|
// XColor tmp[255];
|
||||||
|
// for (i=0;i<255;i++) {
|
||||||
|
// tmp[i].pixel = i;
|
||||||
|
// tmp[i].flags = DoRed|DoGreen|DoBlue;
|
||||||
|
// tmp[i].red = i*256;
|
||||||
|
// tmp[i].green = i*256;
|
||||||
|
// tmp[i].blue = i*256;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// colormap = XCreateColormap(display, RootWindow(display, screen),
|
||||||
|
// DefaultVisual(display, screen), AllocAll);
|
||||||
|
// XStoreColors(display, colormap, tmp, 255);
|
||||||
|
// XSetWindowColormap(display, window, colormap);
|
||||||
|
|
||||||
|
// XSetForeground(display, gc, tmp[16].pixel);
|
||||||
|
|
||||||
|
colormap = DefaultColormap(display, 0);
|
||||||
|
green_gc = XCreateGC(display, window, 0, 0);
|
||||||
|
char green[] = "#008800";
|
||||||
|
XParseColor(display, colormap, green, &green_color);
|
||||||
|
XAllocColor(display, colormap, &green_color);
|
||||||
|
XSetForeground(display, green_gc, green_color.pixel);
|
||||||
|
|
||||||
|
string_gc = XCreateGC(display, window, 0, 0);
|
||||||
|
XSetForeground(display, string_gc, BlackPixel(display, screen));
|
||||||
|
XSetBackground(display, gc, WhitePixel(display, screen));
|
||||||
|
|
||||||
|
int offset_left = 240;
|
||||||
|
|
||||||
|
quit_button = newButton(offset_left, 6, QUIT_COMMAND, strlen(QUIT_COMMAND), quitProgram);
|
||||||
|
offset_left = quit_button.x = 240-(quit_button.width+6);
|
||||||
|
addInput(&quit_button);
|
||||||
|
|
||||||
|
stop_button = newButton(offset_left, 6, STOP_COMMAND, strlen(STOP_COMMAND), stopSockets);
|
||||||
|
offset_left = stop_button.x = offset_left-(stop_button.width+6);
|
||||||
|
addInput(&stop_button);
|
||||||
|
|
||||||
|
start_button = newButton(offset_left, 6, START_COMMAND, strlen(START_COMMAND), startSockets);
|
||||||
|
offset_left = start_button.x = offset_left-(start_button.width+6);
|
||||||
|
addInput(&start_button);
|
||||||
|
|
||||||
|
restart_button = newButton(offset_left, 6, RESTART_COMMAND, strlen(RESTART_COMMAND), startSockets);
|
||||||
|
offset_left = restart_button.x = offset_left-(restart_button.width+6);
|
||||||
|
addInput(&restart_button);
|
||||||
|
|
||||||
|
offset_left = 240;
|
||||||
|
send_button = newButton(offset_left, 300, "send", 4, sendMessage);
|
||||||
|
offset_left = send_button.x = offset_left-(send_button.width+6);
|
||||||
|
addInput(&send_button);
|
||||||
|
|
||||||
|
text_input = newTextInput(offset_left, 300, 27, sendMessage);
|
||||||
|
offset_left = text_input.x = offset_left-(text_input.width+6);
|
||||||
|
addInput(&text_input);
|
||||||
|
|
||||||
|
offset_left = 8;
|
||||||
|
|
||||||
|
list_button = newButton(offset_left, 275, LIST_COMMAND, strlen(LIST_COMMAND), showVariables);
|
||||||
|
offset_left = offset_left+(list_button.width+6);
|
||||||
|
addInput(&list_button);
|
||||||
|
|
||||||
|
redrawInterface();
|
||||||
|
|
||||||
|
XFlush(display);
|
||||||
|
|
||||||
|
interface_fd = ConnectionNumber(display);
|
||||||
|
FD_SET(interface_fd, &master_fds);
|
||||||
|
max_fd = interface_fd;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input newButton(int x, int y, const void* data, size_t size, void(*callback)) {
|
||||||
|
Input new_input;
|
||||||
|
new_input.type = INPUT_BUTTON;
|
||||||
|
new_input.position = 0;
|
||||||
|
new_input.x = x;
|
||||||
|
new_input.y = y;
|
||||||
|
new_input.state = STATE_INACTIVE;
|
||||||
|
new_input.data = malloc(size-1);
|
||||||
|
//strcpy(new_input.data, data);
|
||||||
|
memcpy(new_input.data, data, size);
|
||||||
|
new_input.size = size;
|
||||||
|
new_input.width = new_input.size*7;
|
||||||
|
new_input.height = 13;
|
||||||
|
new_input.callback = callback;
|
||||||
|
new_input.previous = NULL;
|
||||||
|
new_input.next = NULL;
|
||||||
|
return(new_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
Input newTextInput(int x, int y, size_t size, void(*callback)) {
|
||||||
|
Input new_input;
|
||||||
|
new_input.type = INPUT_TEXT;
|
||||||
|
new_input.position = 0;
|
||||||
|
new_input.x = x;
|
||||||
|
new_input.y = y;
|
||||||
|
new_input.state = STATE_INACTIVE;
|
||||||
|
char string[size];
|
||||||
|
int i;
|
||||||
|
for (i=0;i<size;i++) {
|
||||||
|
string[i] = ' ';
|
||||||
|
}
|
||||||
|
string[size] = '\0';
|
||||||
|
|
||||||
|
new_input.data = malloc(size);
|
||||||
|
memcpy(new_input.data, string, size);
|
||||||
|
//strcpy(new_input.data, string);
|
||||||
|
new_input.size = size;
|
||||||
|
new_input.width = new_input.size*7;
|
||||||
|
new_input.height = 13;
|
||||||
|
new_input.callback = callback;
|
||||||
|
new_input.previous = NULL;
|
||||||
|
new_input.next = NULL;
|
||||||
|
return(new_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
Input newInput(int x, int y, const void* data, size_t size, void(*callback)) {
|
||||||
|
Input new_input;
|
||||||
|
new_input.position = 0;
|
||||||
|
new_input.x = x;
|
||||||
|
new_input.y = y;
|
||||||
|
new_input.state = STATE_INACTIVE;
|
||||||
|
new_input.data = malloc(size-1);
|
||||||
|
//strcpy(new_input.data, data);
|
||||||
|
memcpy(new_input.data, data, size);
|
||||||
|
new_input.size = size;
|
||||||
|
new_input.width = new_input.size*7;
|
||||||
|
new_input.height = 13;
|
||||||
|
new_input.callback = callback;
|
||||||
|
new_input.previous = NULL;
|
||||||
|
new_input.next = NULL;
|
||||||
|
return(new_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeInput(Input input) {
|
||||||
|
free(input.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int addInput(Input *input) {
|
||||||
|
if (!last_input) {
|
||||||
|
last_input = input;
|
||||||
|
} else {
|
||||||
|
last_input->next = input;
|
||||||
|
input->previous = last_input;
|
||||||
|
last_input = input;
|
||||||
|
}
|
||||||
|
inputs[input_count] = input;
|
||||||
|
input_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawInput(const Input *input) {
|
||||||
|
if (input->type == INPUT_BUTTON) {
|
||||||
|
if (input->state == STATE_INACTIVE) {
|
||||||
|
XFillRectangle(display, window, string_gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, gc, input->x-2, input->y-2, input->size*7, 13);
|
||||||
|
XFillRectangle(display, window, gc, input->x, input->y, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, gc, input->x, input->y, input->size*7, 13);
|
||||||
|
XDrawString(display, window, string_gc, input->x+(input->size/2)+1, input->y+(11), (char *)input->data, input->size);
|
||||||
|
} else if (input->state == STATE_ACTIVE) {
|
||||||
|
//XDrawRectangle(display, window, gc, input->x-2, input->y-2, input->size*7, 13);
|
||||||
|
XFillRectangle(display, window, string_gc, input->x, input->y, input->size*7, 13); // optional
|
||||||
|
XFillRectangle(display, window, gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawString(display, window, string_gc, input->x-1+(input->size/2)+1, input->y-1+(11), (char *)input->data, input->size);
|
||||||
|
}
|
||||||
|
} else if (input->type == INPUT_TEXT) {
|
||||||
|
drawInputText(input);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawInputText(const Input *input) {
|
||||||
|
if (input->state == STATE_INACTIVE) {
|
||||||
|
XFillRectangle(display, window, gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, string_gc, input->x-2, input->y-2, input->size*7, 13);
|
||||||
|
XFillRectangle(display, window, string_gc, input->x, input->y, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, gc, input->x, input->y, input->size*7, 13);
|
||||||
|
XDrawString(display, window, gc, input->x+(input->size/2)+1, input->y+(11), (char *)input->data, input->size);
|
||||||
|
} else if (input->state == STATE_ACTIVE) {
|
||||||
|
//XDrawRectangle(display, window, gc, input->x-2, input->y-2, input->size*7, 13);
|
||||||
|
XFillRectangle(display, window, string_gc, input->x, input->y, input->size*7, 13); // optional
|
||||||
|
XFillRectangle(display, window, gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawRectangle(display, window, gc, input->x-1, input->y-1, input->size*7, 13);
|
||||||
|
XDrawString(display, window, string_gc, input->x-1+(input->size/2)+1, input->y-1+(11), (char *)input->data, input->size);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closeInterface() {
|
||||||
|
freeInput(quit_button);
|
||||||
|
FD_CLR(interface_fd, &master_fds);
|
||||||
|
XFreeGC(display, gc);
|
||||||
|
XFreeGC(display, string_gc);
|
||||||
|
XDestroyWindow(display, window);
|
||||||
|
XCloseDisplay(display);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int redrawInterface() {
|
||||||
|
//XClearWindow(display, window);
|
||||||
|
XDrawRectangle(display, window, gc, 1, 1, 238, 318);
|
||||||
|
|
||||||
|
Input *current_input;
|
||||||
|
int i;
|
||||||
|
for (i=0;i < input_count; i++) {
|
||||||
|
current_input = inputs[i];
|
||||||
|
if (current_input) {
|
||||||
|
drawInput(current_input);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@ TODO: implement iterator
|
||||||
|
/* while (iterateInput(current_input)) {
|
||||||
|
drawInput(current_input);
|
||||||
|
}*/
|
||||||
|
drawLogo();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iterateInput(Input *input) {
|
||||||
|
if (input->previous == NULL) {
|
||||||
|
printf("lol");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("real lol\n");
|
||||||
|
input = (Input*)input->previous;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int clearInterface() {
|
||||||
|
XClearWindow(display, window);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendMessage(char *str, size_t string_length) {
|
||||||
|
printf("send: %s -- %d\n", (char *)text_input.data, text_input.size);
|
||||||
|
sendMulticast(send_socket, &group_socket, text_input.data, text_input.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleInterface() {
|
||||||
|
while (XPending(display)) {
|
||||||
|
XNextEvent(display, &event);
|
||||||
|
if (event.type == Expose && event.xexpose.count == 0) {
|
||||||
|
redrawInterface();
|
||||||
|
}
|
||||||
|
if (event.type == KeyPress && XLookupString(&event.xkey, key_text, 255, &key, 0) == 1) {
|
||||||
|
/* if (key_text[0] == 'q') {
|
||||||
|
quitProgram();
|
||||||
|
printf("%s\n", QUIT_MESSAGE);
|
||||||
|
}*/
|
||||||
|
if (active_input != NULL) {
|
||||||
|
textInput(active_input, key_text[0]);
|
||||||
|
}
|
||||||
|
redrawInterface(); // lol
|
||||||
|
}
|
||||||
|
if (event.type == ButtonPress) {
|
||||||
|
Input *current_input;
|
||||||
|
int i;
|
||||||
|
if (active_input != NULL) {
|
||||||
|
active_input->state = STATE_INACTIVE;
|
||||||
|
active_input = NULL;
|
||||||
|
}
|
||||||
|
for (i=0;i < input_count; i++) {
|
||||||
|
current_input = inputs[i];
|
||||||
|
if (current_input) {
|
||||||
|
if (event.xbutton.x < current_input->x+current_input->width && event.xbutton.x > current_input->x
|
||||||
|
&& event.xbutton.y < current_input->y+current_input->height && event.xbutton.y > current_input->y) {
|
||||||
|
if (current_input->type == INPUT_TEXT) {
|
||||||
|
active_input = current_input;
|
||||||
|
}
|
||||||
|
current_input->state = STATE_ACTIVE;
|
||||||
|
active_list[active_count] = current_input;
|
||||||
|
active_count++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redrawInterface();
|
||||||
|
} else if (event.type == ButtonRelease) {
|
||||||
|
Input *current_input;
|
||||||
|
int i;
|
||||||
|
for (i=0;i < input_count; i++) {
|
||||||
|
current_input = inputs[i];
|
||||||
|
if (current_input) {
|
||||||
|
if (current_input->state == STATE_ACTIVE) {
|
||||||
|
if (current_input->type == INPUT_TEXT) {
|
||||||
|
//(*current_input->callback)(NULL);
|
||||||
|
} else {
|
||||||
|
(*current_input->callback)(NULL);
|
||||||
|
current_input->state = STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
for (i=0;i<active_count;i++) {
|
||||||
|
if (active_list[i]) {
|
||||||
|
if (active_list[i].type == INPUT_TEXT) {
|
||||||
|
(*active_list[i]->callback)(NULL);
|
||||||
|
} else {
|
||||||
|
(*active_list[i]->callback)(NULL);
|
||||||
|
active_list[i]->state = STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
active_count = 0;*/
|
||||||
|
}
|
||||||
|
redrawInterface(); // lol
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textInput(Input *input, const char character) {
|
||||||
|
printf("%d hmm\n", character);
|
||||||
|
char string[input->size];
|
||||||
|
memcpy(string, input->data, input->size);
|
||||||
|
|
||||||
|
if ((int)character == 8) {// backspace
|
||||||
|
input->position--;
|
||||||
|
string[input->position] = ' ';
|
||||||
|
//string[input->position] = ' ';
|
||||||
|
} else if ((int)character == 13) { // return
|
||||||
|
(*input->callback)(&string, input->size);
|
||||||
|
} else {
|
||||||
|
string[input->position] = character;
|
||||||
|
input->position++;
|
||||||
|
}
|
||||||
|
memcpy(input->data, string, input->size);
|
||||||
|
|
||||||
|
//input->data[1] = character;
|
||||||
|
printf("%c augh\n", character);
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleInput(const char *data_buffer) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showHelp(const char *value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void showVariables() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAttribute(const int attribute) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearAttributes() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove ?
|
||||||
|
void showPrompt() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef X11_H
|
||||||
|
#define X11_H
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "x11_assets.h"
|
||||||
|
|
||||||
|
#include "../ui_common.h"
|
||||||
|
#include "../common.h"
|
||||||
|
#include "../net.h"
|
||||||
|
#include "../macros.h"
|
||||||
|
|
||||||
|
Display *display;
|
||||||
|
Window window;
|
||||||
|
int screen;
|
||||||
|
GC gc;
|
||||||
|
GC tmp_gc;
|
||||||
|
GC string_gc;
|
||||||
|
XColor tmp_color;
|
||||||
|
|
||||||
|
XEvent event;
|
||||||
|
KeySym key;
|
||||||
|
char key_text[255];
|
||||||
|
|
||||||
|
XTextItem x_logo;
|
||||||
|
|
||||||
|
// colors
|
||||||
|
Colormap colormap;
|
||||||
|
GC green_gc;
|
||||||
|
XColor green_color;
|
||||||
|
|
||||||
|
int redrawInterface();
|
||||||
|
|
||||||
|
/* buttons */
|
||||||
|
Input quit_button;
|
||||||
|
Input start_button;
|
||||||
|
Input stop_button;
|
||||||
|
Input restart_button;
|
||||||
|
Input list_button;
|
||||||
|
Input test_input;
|
||||||
|
Input send_button;
|
||||||
|
|
||||||
|
Input text_input;
|
||||||
|
|
||||||
|
Input newButton(int x, int y, const void* data, size_t size, void(*callback));
|
||||||
|
Input newInput(int x, int y, const void* data, size_t size, void(*callback));
|
||||||
|
Input newTextInput(int x, int y, size_t size, void(*callback));
|
||||||
|
|
||||||
|
void textInput(Input *input, const char character);
|
||||||
|
|
||||||
|
int iterateInput(Input *input);
|
||||||
|
int addInput(Input *input);
|
||||||
|
void freeInput(Input input);
|
||||||
|
int drawInput(const Input *input);
|
||||||
|
|
||||||
|
int drawInputText(const Input *input);
|
||||||
|
|
||||||
|
void sendMessage(char *str, size_t string_length);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef X11_ASSETS_H
|
||||||
|
#define X11_ASSETS_H
|
||||||
|
|
||||||
|
#define INPUT_BUTTON 1
|
||||||
|
#define INPUT_TEXT 2
|
||||||
|
|
||||||
|
#define STATE_INACTIVE 0
|
||||||
|
#define STATE_ACTIVE 1
|
||||||
|
|
||||||
|
int button_count;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int state;
|
||||||
|
int length;
|
||||||
|
char *string;
|
||||||
|
struct Button *next;
|
||||||
|
struct Button *previous;
|
||||||
|
void(*callback)();
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int type;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int state;
|
||||||
|
int size;
|
||||||
|
int position;
|
||||||
|
void *data;
|
||||||
|
struct Input *next;
|
||||||
|
struct Input *previous;
|
||||||
|
void(*callback)();
|
||||||
|
} Input;
|
||||||
|
|
||||||
|
int input_count;
|
||||||
|
Input *last_input;
|
||||||
|
Input *inputs[128];
|
||||||
|
|
||||||
|
Input *active_input;
|
||||||
|
|
||||||
|
Button *last_button;
|
||||||
|
Button *buttons[128];
|
||||||
|
|
||||||
|
int active_count;
|
||||||
|
Input *active_list[15];
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue