diff --git a/netsl/.gitignore b/netsl/.gitignore new file mode 100644 index 0000000..1382995 --- /dev/null +++ b/netsl/.gitignore @@ -0,0 +1,8 @@ +bin/ +out/ +net +test +*.o +*.swp +a.out +netsl diff --git a/netsl/Makefile b/netsl/Makefile new file mode 100644 index 0000000..461a063 --- /dev/null +++ b/netsl/Makefile @@ -0,0 +1,22 @@ + +CFLAGS=-g -Wall -Wextra -std=gnu99 +BIN=bin +SRC=src +LIBS=-lncurses +TARGET=netsl +OBJECTS=$(BIN)/main.o $(BIN)/msg.o $(BIN)/net.o $(BIN)/display.o $(BIN)/image.o + +all: $(BIN) $(TARGET) + +$(BIN): + mkdir -pv $(BIN) + +$(TARGET): $(OBJECTS) + gcc $^ $(LIBS) -o $(TARGET) + +$(BIN)/%.o: $(SRC)/%.c $(SRC)/%.h + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + rm -rf $(BIN) + rm $(TARGET) diff --git a/netsl/README b/netsl/README new file mode 100644 index 0000000..540df59 --- /dev/null +++ b/netsl/README @@ -0,0 +1,8 @@ + +must read: http://www.beej.us/guide/bgnet/ +zu c99: http://www.c-plusplus.de/forum/296310-full + +00000000011111111112222222222333333333344444444445555555555666666666677777777778 +1234567890 1234567890 1234567890 1234567890 + 1234567890 1234567890 1234567890 1234567890 + diff --git a/netsl/image b/netsl/image new file mode 100644 index 0000000..271b9db --- /dev/null +++ b/netsl/image @@ -0,0 +1,44 @@ + _,-%/%| + _,-' \//%\ + _,-' \%/|% + / / ) __,-- /%\ + \__/_,-'%(% ; %)% + %\%, %\ + '--%' + +.. + _,-%/%| + _,-' \//%\ + _,-' \%/|% + / / ) __,-- /%\ + \__/_,-'%(% ; %)% + / %\%, %\ + '--%' + +.. + _,-%/%| + _,-' \//%\ + _,-' \%/|% + / / ) __,-- /%\ + \__/_,-'%(% ; %)% + / %\%, %\ + / '--%' + +.. + _,-%/%| + _,-' \//%\ + _,-' \%/|% + / / ) __,-- /%\ + \__/_,-'%(% ; %)% + %\%, %\ + / '--%' + / +.. + _,-%/%| + _,-' \//%\ + _,-' \%/|% + / / ) __,-- /%\ + \__/_,-'%(% ; %)% + %\%, %\ + '--%' + / diff --git a/netsl/original_sl/sl-3.03.orig/Makefile b/netsl/original_sl/sl-3.03.orig/Makefile new file mode 100644 index 0000000..d525743 --- /dev/null +++ b/netsl/original_sl/sl-3.03.orig/Makefile @@ -0,0 +1,14 @@ +#========================================== +# Makefile: makefile for sl +# Copyright 1993,1998 Toyoda Masashi +# (toyoda@is.titech.ac.jp) +# Last Modified: 1998/ 7/22 +#========================================== + +CC=cc +CFLAGS=-O + +sl: sl.c sl.h + $(CC) $(CFLAGS) -o sl sl.c -lcurses -ltermcap +# $(CC) $(CFLAGS) -o sl sl.c -lcurses + diff --git a/netsl/original_sl/sl-3.03.orig/sl.c b/netsl/original_sl/sl-3.03.orig/sl.c new file mode 100644 index 0000000..474d4f4 --- /dev/null +++ b/netsl/original_sl/sl-3.03.orig/sl.c @@ -0,0 +1,225 @@ +/*======================================== + * sl.c: + * Copyright 1993,1998 Toyoda Masashi + * (toyoda@is.titech.ac.jp) + * Last Modified: 1998/ 7/22 + *======================================== + */ +/* sl version 3.03 : add usleep(20000) */ +/* by Toyoda Masashi 1998/ 7/22 */ +/* sl version 3.02 : D51 flies! Change options. */ +/* by Toyoda Masashi 1993/ 1/19 */ +/* sl version 3.01 : Wheel turns smoother */ +/* by Toyoda Masashi 1992/12/25 */ +/* sl version 3.00 : Add d(D51) option */ +/* by Toyoda Masashi 1992/12/24 */ +/* sl version 2.02 : Bug fixed.(dust remains in screen) */ +/* by Toyoda Masashi 1992/12/17 */ +/* sl version 2.01 : Smoke run and disappear. */ +/* Change '-a' to accident option. */ +/* by Toyoda Masashi 1992/12/16 */ +/* sl version 2.00 : Add a(all),l(long),F(Fly!) options. */ +/* by Toyoda Masashi 1992/12/15 */ +/* sl version 1.02 : Add turning wheel. */ +/* by Toyoda Masashi 1992/12/14 */ +/* sl version 1.01 : Add more complex smoke. */ +/* by Toyoda Masashi 1992/12/14 */ +/* sl version 1.00 : SL runs vomitting out smoke. */ +/* by Toyoda Masashi 1992/12/11 */ + +#include +#include +#include +#include "sl.h" + +int ACCIDENT = 0; +int LOGO = 0; +int FLY = 0; + +int my_mvaddstr(int y, int x, char *str) +{ + for ( ; x < 0; ++x, ++str) + if (*str == '\0') return ERR; + for ( ; *str != '\0'; ++str, ++x) + if (mvaddch(y, x, *str) == ERR) return ERR; + return OK; +} + +void option(char *str) +{ + extern int ACCIDENT, FLY, LONG; + + while (*str != '\0') { + switch (*str++) { + case 'a': ACCIDENT = 1; break; + case 'F': FLY = 1; break; + case 'l': LOGO = 1; break; + default: break; + } + } +} + +void main(int argc, char *argv[]) +{ + int x, i; + + for (i = 1; i < argc; ++i) { + if (*argv[i] == '-') { + option(argv[i] + 1); + } + } + initscr(); + signal(SIGINT, SIG_IGN); + noecho(); + leaveok(stdscr, TRUE); + scrollok(stdscr, FALSE); + + for (x = COLS - 1; ; --x) { + if (LOGO == 0) { + if (add_D51(x) == ERR) break; + } else { + if (add_sl(x) == ERR) break; + } + refresh(); + usleep(20000); + } + mvcur(0, COLS - 1, LINES - 1, 0); + endwin(); +} + + +int add_sl(int x) +{ + static char *sl[LOGOPATTERNS][LOGOHIGHT + 1] + = {{LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN}, + {LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN}, + {LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN}, + {LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN}, + {LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN}, + {LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}}; + + static char *coal[LOGOHIGHT + 1] + = {LCOAL1, LCOAL2, LCOAL3, LCOAL4, LCOAL5, LCOAL6, DELLN}; + + static char *car[LOGOHIGHT + 1] + = {LCAR1, LCAR2, LCAR3, LCAR4, LCAR5, LCAR6, DELLN}; + + int i, y, py1 = 0, py2 = 0, py3 = 0; + + if (x < - LOGOLENGTH) return ERR; + y = LINES / 2 - 3; + + if (FLY == 1) { + y = (x / 6) + LINES - (COLS / 6) - LOGOHIGHT; + py1 = 2; py2 = 4; py3 = 6; + } + for (i = 0; i <= LOGOHIGHT; ++i) { + my_mvaddstr(y + i, x, sl[(LOGOLENGTH + x) / 3 % LOGOPATTERNS][i]); + my_mvaddstr(y + i + py1, x + 21, coal[i]); + my_mvaddstr(y + i + py2, x + 42, car[i]); + my_mvaddstr(y + i + py3, x + 63, car[i]); + } + if (ACCIDENT == 1) { + add_man(y + 1, x + 14); + add_man(y + 1 + py2, x + 45); add_man(y + 1 + py2, x + 53); + add_man(y + 1 + py3, x + 66); add_man(y + 1 + py3, x + 74); + } + add_smoke(y - 1, x + LOGOFUNNEL); + return OK; +} + + +add_D51(int x) +{ + static char *d51[D51PATTERNS][D51HIGHT + 1] + = {{D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL11, D51WHL12, D51WHL13, D51DEL}, + {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL21, D51WHL22, D51WHL23, D51DEL}, + {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL31, D51WHL32, D51WHL33, D51DEL}, + {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL41, D51WHL42, D51WHL43, D51DEL}, + {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL51, D51WHL52, D51WHL53, D51DEL}, + {D51STR1, D51STR2, D51STR3, D51STR4, D51STR5, D51STR6, D51STR7, + D51WHL61, D51WHL62, D51WHL63, D51DEL}}; + static char *coal[D51HIGHT + 1] + = {COAL01, COAL02, COAL03, COAL04, COAL05, + COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL}; + + int y, i, dy = 0; + + if (x < - D51LENGTH) return ERR; + y = LINES / 2 - 5; + + if (FLY == 1) { + y = (x / 7) + LINES - (COLS / 7) - D51HIGHT; + dy = 1; + } + for (i = 0; i <= D51HIGHT; ++i) { + my_mvaddstr(y + i, x, d51[(D51LENGTH + x) % D51PATTERNS][i]); + my_mvaddstr(y + i + dy, x + 53, coal[i]); + } + if (ACCIDENT == 1) { + add_man(y + 2, x + 43); + add_man(y + 2, x + 47); + } + add_smoke(y - 1, x + D51FUNNEL); + return OK; +} + + +int add_man(int y, int x) +{ + static char *man[2][2] = {{"", "(O)"}, {"Help!", "\\O/"}}; + int i; + + for (i = 0; i < 2; ++i) { + my_mvaddstr(y + i, x, man[(LOGOLENGTH + x) / 12 % 2][i]); + } +} + + +int add_smoke(int y, int x) +#define SMOKEPTNS 16 +{ + static struct smokes { + int y, x; + int ptrn, kind; + } S[1000]; + static int sum = 0; + static char *Smoke[2][SMOKEPTNS] + = {{"( )", "( )", "( )", "( )", "( )", + "( )" , "( )" , "( )" , "()" , "()" , + "O" , "O" , "O" , "O" , "O" , + " " }, + {"(@@@)", "(@@@@)", "(@@@@)", "(@@@)", "(@@)", + "(@@)" , "(@)" , "(@)" , "@@" , "@@" , + "@" , "@" , "@" , "@" , "@" , + " " }}; + static char *Eraser[SMOKEPTNS] + = {" ", " ", " ", " ", " ", + " " , " " , " " , " " , " " , + " " , " " , " " , " " , " " , + " " }; + static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }; + static int dx[SMOKEPTNS] = {-2, -1, 0, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 3 }; + int i; + + if (x % 4 == 0) { + for (i = 0; i < sum; ++i) { + my_mvaddstr(S[i].y, S[i].x, Eraser[S[i].ptrn]); + S[i].y -= dy[S[i].ptrn]; + S[i].x += dx[S[i].ptrn]; + S[i].ptrn += (S[i].ptrn < SMOKEPTNS - 1) ? 1 : 0; + my_mvaddstr(S[i].y, S[i].x, Smoke[S[i].kind][S[i].ptrn]); + } + my_mvaddstr(y, x, Smoke[sum % 2][0]); + S[sum].y = y; S[sum].x = x; + S[sum].ptrn = 0; S[sum].kind = sum % 2; + sum ++; + } +} diff --git a/netsl/original_sl/sl-3.03.orig/sl.h b/netsl/original_sl/sl-3.03.orig/sl.h new file mode 100644 index 0000000..fd5055c --- /dev/null +++ b/netsl/original_sl/sl-3.03.orig/sl.h @@ -0,0 +1,104 @@ +/*======================================== + * sl.h: Text data of SL version 3.01 + * Copyright 1993 Toyoda Masashi + * (toyoda@is.titech.ac.jp) + * Last Modified: 1992/12/23 + *======================================== + */ + +#define D51HIGHT 10 +#define D51FUNNEL 7 +#define D51LENGTH 83 +#define D51PATTERNS 6 + + +#define D51STR1 " ==== ________ ___________ " +#define D51STR2 " _D _| |_______/ \\__I_I_____===__|_________| " +#define D51STR3 " |(_)--- | H\\________/ | | =|___ ___| " +#define D51STR4 " / | | H | | | | ||_| |_|| " +#define D51STR5 " | | | H |__--------------------| [___] | " +#define D51STR6 " | ________|___H__/__|_____/[][]~\\_______| | " +#define D51STR7 " |/ | |-----------I_____I [][] [] D |=======|__ " + +#define D51WHL11 "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ " +#define D51WHL12 " |/-=|___|= || || || |_____/~\\___/ " +#define D51WHL13 " \\_/ \\O=====O=====O=====O_/ \\_/ " + +#define D51WHL21 "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ " +#define D51WHL22 " |/-=|___|=O=====O=====O=====O |_____/~\\___/ " +#define D51WHL23 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ " + +#define D51WHL31 "__/ =| o |=-O=====O=====O=====O \\ ____Y___________|__ " +#define D51WHL32 " |/-=|___|= || || || |_____/~\\___/ " +#define D51WHL33 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ " + +#define D51WHL41 "__/ =| o |=-~O=====O=====O=====O\\ ____Y___________|__ " +#define D51WHL42 " |/-=|___|= || || || |_____/~\\___/ " +#define D51WHL43 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ " + +#define D51WHL51 "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ " +#define D51WHL52 " |/-=|___|= O=====O=====O=====O|_____/~\\___/ " +#define D51WHL53 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ " + +#define D51WHL61 "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__ " +#define D51WHL62 " |/-=|___|= || || || |_____/~\\___/ " +#define D51WHL63 " \\_/ \\_O=====O=====O=====O/ \\_/ " + +#define D51DEL " " + +#define COAL01 " " +#define COAL02 " " +#define COAL03 " _________________ " +#define COAL04 " _| \\_____A " +#define COAL05 " =| | " +#define COAL06 " -| | " +#define COAL07 "__|________________________|_ " +#define COAL08 "|__________________________|_ " +#define COAL09 " |_D__D__D_| |_D__D__D_| " +#define COAL10 " \\_/ \\_/ \\_/ \\_/ " + +#define COALDEL " " + +#define LOGOHIGHT 6 +#define LOGOFUNNEL 4 +#define LOGOLENGTH 84 +#define LOGOPATTERNS 6 + +#define LOGO1 " ++ +------ " +#define LOGO2 " || |+-+ | " +#define LOGO3 " /---------|| | | " +#define LOGO4 " + ======== +-+ | " + +#define LWHL11 " _|--O========O~\\-+ " +#define LWHL12 "//// \\_/ \\_/ " + +#define LWHL21 " _|--/O========O\\-+ " +#define LWHL22 "//// \\_/ \\_/ " + +#define LWHL31 " _|--/~O========O-+ " +#define LWHL32 "//// \\_/ \\_/ " + +#define LWHL41 " _|--/~\\------/~\\-+ " +#define LWHL42 "//// \\_O========O " + +#define LWHL51 " _|--/~\\------/~\\-+ " +#define LWHL52 "//// \\O========O/ " + +#define LWHL61 " _|--/~\\------/~\\-+ " +#define LWHL62 "//// O========O_/ " + +#define LCOAL1 "____ " +#define LCOAL2 "| \\@@@@@@@@@@@ " +#define LCOAL3 "| \\@@@@@@@@@@@@@_ " +#define LCOAL4 "| | " +#define LCOAL5 "|__________________| " +#define LCOAL6 " (O) (O) " + +#define LCAR1 "____________________ " +#define LCAR2 "| ___ ___ ___ ___ | " +#define LCAR3 "| |_| |_| |_| |_| | " +#define LCAR4 "|__________________| " +#define LCAR5 "|__________________| " +#define LCAR6 " (O) (O) " + +#define DELLN " " diff --git a/netsl/original_sl/sl-3.03.orig/sl.txt b/netsl/original_sl/sl-3.03.orig/sl.txt new file mode 100644 index 0000000..9af080d --- /dev/null +++ b/netsl/original_sl/sl-3.03.orig/sl.txt @@ -0,0 +1,23 @@ +------------------------------------------------------------------------------- + ==== ________ ___________ + _D _| |_______/ \__I_I_____===__|_________| + |(_)--- | H\________/ | | =|___ ___| + / | | H | | | | ||_| |_|| + | | | H |__--------------------| [___] | + | ________|___H__/__|_____/[][]~\_______| | + |/ | |-----------I_____I [][] [] D |=======|__ +__/ =| o |=-~~\ /~~\ /~~\ /~~\ ____Y___________|__ + |/-=|___|| || || || |_____/~\___/ + \_/ \__/ \__/ \__/ \__/ \_/ +------------------------------------------------------------------------------- + + + _________________ + _| \_____A + =| | + -| | +__|________________________|_ +|__________________________|_ + |_D__D__D_| |_D__D__D_| + \_/ \_/ \_/ \_/ +------------------------------------------------------------------------------- \ No newline at end of file diff --git a/netsl/original_sl/sl_3.03-17.debian.tar.gz b/netsl/original_sl/sl_3.03-17.debian.tar.gz new file mode 100644 index 0000000..020474d Binary files /dev/null and b/netsl/original_sl/sl_3.03-17.debian.tar.gz differ diff --git a/netsl/original_sl/sl_3.03.orig.tar.gz b/netsl/original_sl/sl_3.03.orig.tar.gz new file mode 100644 index 0000000..6c21b95 Binary files /dev/null and b/netsl/original_sl/sl_3.03.orig.tar.gz differ diff --git a/netsl/pic b/netsl/pic new file mode 100644 index 0000000..f2bcf08 --- /dev/null +++ b/netsl/pic @@ -0,0 +1,21 @@ + + + + (******) + (*****) + (****) + (***) + (**) + [~] + | | (~) (~) (~) /~~~~~~~~~~~~ + /~~~~~~~~~~~~~~~~~~~~~~~ [~_~_] | * * * /~~~~~~~~~~~| + [| %___________________ | |~~~~~~~~ | + //\[___] ___ ___ ___\ | | | + /// [___+/-+-\-/-+-\-/-+ \\_________|=|____________________|= + //// @-=-@ \___/ \___/ \___/ @-==-@ @-==-@ @-==-@ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + + + diff --git a/netsl/src/display.c b/netsl/src/display.c new file mode 100644 index 0000000..a5ad5f6 --- /dev/null +++ b/netsl/src/display.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +#include "msg.h" +#include "display.h" + +void setup_display() { + initscr(); // ncurses initialization + curs_set(0); // invisible cursor +} + +void cleanup_display() { + endwin(); // clean ncurses shutdown +} + +/* + image[row][col] >>> image[row*width+col]; + + uint32_t width; // normally 80 + uint32_t height; // normally 25, may vary + char *image; // dimension is width x height +*/ +static void print_current_image(const struct message* msg, int start, int end) { + end = 80; // end is ignored and 80 is used, should be handled properly later + + //move(0,0); // start in the upper left corner + char *pic = msg->image; // get a ptr to the actual image + + for (int row=0; row < 25; row++) { // iterate over rows + char *original_line = pic + row * msg->width; // pointer to the start of the line to print + char *line = (char*) malloc(end-start+1); // allocate a line because we modify it + strcpy(line, original_line + start); // get a line from the right start + line[end-start] = '\0'; // terminate it + + mvprintw(row, 0, "%s", line); // print it + free(line); // free it + } + + refresh(); // refresh the screen +} + + +void prntscreen(const struct message *msg, const struct prog_info *pinfo); + +void callback(const struct message *msg, const struct prog_info *pinfo) { + //printf("in callback, tst=%d\n", msg->timestamp); + + // calculate the actual offset to use + //int start = msg->timestamp % msg->width + pinfo->client_offset; + //print_current_image(msg, start, start+80); + + prntscreen(msg, pinfo); +} + + +//int init = 0; +//int rows; +//int cols; +void prntscreen(const struct message *msg, const struct prog_info *pinfo) { + static int init = 0; + static int rows; + static int cols; + static char *img = NULL; + static int w; + static int h; + static int f; + if (!img && msg->image) { + img = msg->image; + w = msg->width; + h = msg->height; + f = msg->frames; + } + if (!img) { + printf("awaiting state ... %d\r", msg->timestamp); + return; + } + + if (!init) { +// printf("init start\n"); + initscr(); + curs_set(0); // invisible cursor + getmaxyx(stdscr, rows, cols); + + init = 1; +// printf("init end\n"); + } + + int frame = msg->timestamp; + int right = pinfo->client_offset; + int left = right + cols; + +// for (int y=0; yheight; y++) { + for (int x=left-frame; x=w-1?' ':img[imgoff+(y*w+p)]); + } + } + + refresh(); +} diff --git a/netsl/src/display.h b/netsl/src/display.h new file mode 100644 index 0000000..c85f409 --- /dev/null +++ b/netsl/src/display.h @@ -0,0 +1,14 @@ +#ifndef __DISPLAY +#define __DISPLAY + +#include +#include "msg.h" +#include "misc.h" + +void setup_display(); +void cleanup_display(); + +void callback(const struct message *msg, const struct prog_info *pinfo); + +#endif + diff --git a/netsl/src/image.c b/netsl/src/image.c new file mode 100644 index 0000000..31bc33e --- /dev/null +++ b/netsl/src/image.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include // MAX + +#include "image.h" + +#define LINELEN 20000 + +char *readImage(const char* filename, int *cols, int *rows, int *imgz) { + + printf("fopen\n"); + FILE *f = fopen(filename, "r"); + printf("ok\n"); + + *cols = 0; + *rows = 0; + int maxrows = 0; + *imgz = 1; + char *linebuf = (char *)malloc(LINELEN); + char *ret = NULL; + if (f) { + while (fgets(linebuf, LINELEN, f)) { + int len = strlen(linebuf); + if ( len > 2 && linebuf[0] == '.' && linebuf[1] == '.') { + (*imgz)++; + (*rows)=0; + } + *cols = len>*cols?len:*cols; + (*rows)++; + maxrows = (*rows>maxrows)?*rows:maxrows; + } + (*rows)=maxrows; + + (*cols)--; + ret = (char *)malloc(*imgz * *cols * *rows + 1); + memset(ret, ' ', *imgz * *cols * *rows); + fseek(f, 0, SEEK_SET); + + for (int fp=0; fp<(*imgz); fp++) { + for (int r=0; r<*rows; r++) { + int base = (fp * *rows * *cols) + r * *cols; + fgets(&ret[base], LINELEN, f); + if (ret[base] == '.' && ret[base+1] == '.') { + ret[base] = ' '; + ret[base+1] = ' '; + break; + } + } + } + for (int i=0; i < (*imgz * *cols * *rows); i++) + if (ret[i] == '\n' || ret[i] == '\r') + ret[i] = ' '; + + fclose(f); + } + free(linebuf); + + printf("image size: %d x %d\n%d frames\n", *cols, *rows, *imgz); + + for (int y=0; y < *rows; y++) { + for (int x=0; x < *cols; x++) { + //mvaddch(y,x,img[y * *cols +x]); + printf("%c", ret[y * *cols +x]); + } + printf("\n"); + } + + return ret; +} + + diff --git a/netsl/src/image.h b/netsl/src/image.h new file mode 100644 index 0000000..75f8e0b --- /dev/null +++ b/netsl/src/image.h @@ -0,0 +1,6 @@ +#ifndef __IMAGE +#define __IMAGE + +char *readImage(const char* filename, int *cols, int *rows, int *imgz); + +#endif diff --git a/netsl/src/main.c b/netsl/src/main.c new file mode 100644 index 0000000..2724f5b --- /dev/null +++ b/netsl/src/main.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include + + +#include "misc.h" +#include "net.h" +#include "display.h" +#include "image.h" + +#define MODE_SERVER 0 +#define MODE_CLIENT 1 + +void die() { + cleanup_display(); + exit(1); +} + +int parseArgs(struct prog_info *pinfo, int argc, char **argv) { + pinfo->mode = MODE_SERVER; + pinfo->client_offset = 1; + pinfo->port = 4711; + pinfo->fps = 10; + pinfo->width = -1; + pinfo->filename = NULL; + + if (argc <= 1) { + printf("usage: %s [-s|-c ] [-p ] [-t ] [-w ] -i \n", argv[0]); + printf("where:\n -s run in server mode\n"); + printf( " -c run in client mode\n"); + printf( " off is the column offset to use.\n"); + printf( " -p use the specified port\n"); + printf( " -t when in server mode: update times\n"); + printf( " per second. Valid range: 2 - 99\n"); + printf( " ignored in client mode\n"); + printf( " -w maximum width of the whole field. server only.\n"); + printf( " -i image filename. server only\n"); + printf("\n\n"); + return -1; + } + int i; + for (i=1; imode = MODE_SERVER; + continue; + } + if (strncmp(argv[i], "-c", 2) == 0) { + pinfo->mode = MODE_CLIENT; + if (argc <= i+1) { + printf("client number not specified\n"); + return -2; + } + pinfo->client_offset = (int)strtol(argv[++i], NULL, 10); + if (pinfo->client_offset <= 0) { + printf("invalid client number!\n"); + return -3; + } + continue; + } + if (strncmp(argv[i], "-p", 2) == 0) { + if (argc <= i+1) { + printf("port not specified\n"); + return -4; + } + pinfo->port = (int)strtol(argv[++i], NULL, 10); + if (pinfo->port <= 0 || 65536 <= pinfo->port) { + printf("invalid port number!\n"); + return -5; + } + continue; + } + if (strncmp(argv[i], "-t", 2) == 0) { + if (argc <= i+1) { + printf("fps not specified\n"); + return -6; + } + pinfo->fps = (int)strtol(argv[++i], NULL, 10); + if (pinfo->fps <= 1 || 100 <= pinfo->fps) { + printf("fps invalid!\n"); + return -7; + } + continue; + } + if (strncmp(argv[i], "-w", 2) == 0) { + if (argc <= i+1) { + printf("width not specified\n"); + return -8; + } + pinfo->width = (int)strtol(argv[++i], NULL, 10); + if (pinfo->width <= 1) { + printf("width invalid!\n"); + return -9; + } + continue; + } + if (strncmp(argv[i], "-i", 2) == 0) { + if (argc <= i+1) { + printf("image filename not specified\n"); + return -10; + } + pinfo->filename = argv[++i]; + continue; + } + printf("unknown argument %s\n", argv[i]); + return -11; + } + + return 0; +} + + +int main(int argc, char **argv) { + + int ret; + if ((ret = parseArgs(&prog_info, argc, argv)) == 0) { + + printf("port: %d\n", prog_info.port); + if (prog_info.mode == MODE_SERVER) { + printf("running in SERVER mode @%d FPS\n", prog_info.fps); + if (!prog_info.filename) { + printf("no image given\n"); + return -12; + } + int w, h, i; + char *image = readImage(prog_info.filename, &w, &h, &i); + if (!image) { + printf("could not read image!\n"); + return -13; + } + prog_info.width = prog_info.width>(w*2)?prog_info.width:(w*2); + ret = run_server(&prog_info, image, w, h, i); + } else { + printf("running in CLIENT mode, using client offset %d\n", prog_info.client_offset); + signal(SIGINT,&die); + signal(SIGTERM,&die); + ret = run_client(&prog_info, callback); + } + + } + return ret; +} + diff --git a/netsl/src/main.h b/netsl/src/main.h new file mode 100644 index 0000000..0bfc895 --- /dev/null +++ b/netsl/src/main.h @@ -0,0 +1,14 @@ +// nüscht ... +// +// +// +// +// _,-%/%| +// _,-' \//%\ +// _,-' \%/|% +// / / ) __,-- /%\ +// \__/_,-'%(% ; %)% +// / %\%, %\ +// / '--%' +// / +// diff --git a/netsl/src/misc.h b/netsl/src/misc.h new file mode 100644 index 0000000..fa8f428 --- /dev/null +++ b/netsl/src/misc.h @@ -0,0 +1,14 @@ +#ifndef __MISC +#define __MISC + +struct prog_info { + int mode; + int client_offset; + int port; + int fps; + int width; + char *filename; +} prog_info; + +#endif + diff --git a/netsl/src/msg.c b/netsl/src/msg.c new file mode 100644 index 0000000..aff3a2f --- /dev/null +++ b/netsl/src/msg.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include // htonl +#include "msg.h" + +int getBufferSize(struct message *msg) { + return 4*sizeof(uint32_t) + msg->width * msg->height * msg->frames; +} + +void serialize (char *buf, struct message *msg) { + memcpy(&buf[0], &msg->timestamp, 4); + memcpy(&buf[4], &msg->width, 4); + memcpy(&buf[8], &msg->height, 4); + memcpy(&buf[12], &msg->frames, 4); + if (msg->width * msg->height) + memcpy(&buf[16], msg->image, msg->frames * msg->width * msg->height); +} + +void deserialize (struct message *msg, const char *buf) { + memcpy(&msg->timestamp, &buf[0], 4); + memcpy(&msg->width, &buf[4], 4); + memcpy(&msg->height, &buf[8], 4); + memcpy(&msg->frames, &buf[12], 4); + if (msg->width * msg->height) { + msg->image = (char*) malloc(msg->width * msg->height * msg->frames); + memcpy(msg->image, &buf[16], msg->width * msg->height * msg->frames); + } else { + msg->image = NULL; + } +} + +/* Buffer ist nicht erforderlich + +struct Buffer *new_buffer() { + struct Buffer *b = malloc(sizeof(Buffer)); + + b->data = malloc(0); + b->size = 0; + + return b; +} + +void append_space(Buffer * b, int n) { + b->size += n; + b->data = realloc(b->data, b->size); +} + +void serialize_int(int x, Buffer * b) { + // htonl :: uint32_t -> uint32_t -- converts the parameter from host byte order to network byte order + //x = htonl(x); + + append_space(b, sizeof(int)); + + memcpy( ((char*)b->data) + b->size, &x, sizeof(int)); + b->size += sizeof(int); +} + +void serialize_string(char *str, Buffer *b) { + + int newlen = strlen(str); + + append_space(b, newlen); + + int i = 0; + while (i < newlen) { + memcpy( ((char*)b->data) + b->size + i, str, sizeof(char)); + str++; + i++; + } + + b->size += newlen; + +} + +void serialize_message(struct message *msg, Buffer *b) { + serialize_int(msg->timestamp, b); // does this also work for long? + serialize_int(msg->width, b); + serialize_int(msg->height, b); + for (int i=0; i < msg->width; i++) + serialize_string(msg->image[i], b); +} + +int main() { + + Buffer *buf = new_buffer(); + //serialize_string("lol", buf); + serialize_int(42, buf); + printf("buf: size:%d data:%p\n", buf->size, buf->data); + +} +*/ + diff --git a/netsl/src/msg.h b/netsl/src/msg.h new file mode 100644 index 0000000..b90056c --- /dev/null +++ b/netsl/src/msg.h @@ -0,0 +1,37 @@ +#ifndef __MSG +#define __MSG + +#include + +//typedef struct Buffer { +// int size; +// void *data; +//} Buffer; + +struct message { + uint32_t timestamp; + uint32_t width; // normally 80 + uint32_t height; // normally 25, may vary + uint32_t frames; // number of frames + //char **image; // dimension is width x height + char *image; // dimension is width x height +/* + * image[row][col] >>> image[row*width+col]; + */ + +}; + +int getBufferSize(struct message *msg); +void serialize(char *buf,struct message *msg); +void deserialize(struct message *msg,const char *buf); + +/* +struct Buffer *new_buffer(); +void append_space(Buffer *b,int n); +void serialize_int(int x,Buffer *b); +void serialize_string(char *str,Buffer *b); +void serialize_message(struct message *msg,Buffer *b); +*/ + +#endif + diff --git a/netsl/src/net.c b/netsl/src/net.c new file mode 100644 index 0000000..0e01397 --- /dev/null +++ b/netsl/src/net.c @@ -0,0 +1,188 @@ +#include +#include +#include + +#include // ? +#include // geguttenbergt aus bejees networking guide +#include // ? + +// networking +#include +#include +#include +#include +#include + +#include // nanosleep + +#include "net.h" + + +// little helper +static void *get_in_addr(struct sockaddr *sa) { + switch (sa->sa_family) { + case AF_INET: + return &(((struct sockaddr_in*)sa)->sin_addr); + break; + case AF_INET6: + return &(((struct sockaddr_in6*)sa)->sin6_addr); + break; + case AF_UNSPEC: + default: + return NULL; + } +} + + +// server mode +// pumpt im for(;;) den status ins eth +// +int run_server(const struct prog_info *pinfo, char *img, int w, int h, int frms) { + struct addrinfo hints, *servinfo, *p; + int ret; + int sockfd; + char portbuf[6]; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + sprintf(portbuf, "%d", pinfo->port); + if ((ret = getaddrinfo("255.255.255.255", portbuf, &hints, &servinfo)) != 0) { + fprintf(stderr, "so getaddrinfo error: %s\n", gai_strerror(ret)); + return 1; + } + + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { + perror("talker: much socket error"); + continue; + } + break; + } + + if (p == NULL) { + fprintf(stderr, "talker: such fail to bind socket\n"); + return 2; + } + + struct timespec tim; + tim.tv_sec = 0; + tim.tv_nsec = 1000000000 / pinfo->fps; + + // Einem Socket muss das Broadcasting explizit erlaubt werden: + int broadcastPermission = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission, sizeof(broadcastPermission)) < 0){ + fprintf(stderr, "very setsockopt error"); + exit(1); + } + + // + int t = 0; + for (;;) { + //printf("sending...\n"); + int numbytes; + + t++; + t %= pinfo->width; + struct message *outmsg = (struct message *) malloc(sizeof(struct message)); + outmsg->timestamp = (uint32_t)t; //(uint32_t)time(NULL); + // send image every 100 frames + bool sendimg = (t % 100) == 0; + outmsg->width = sendimg ? w : 0; + outmsg->height = sendimg ? h : 0; + outmsg->frames = sendimg ? frms: 0; + outmsg->image = sendimg ? img : NULL; + + int buflen = getBufferSize(outmsg); + char *outbuf = (char *) malloc(buflen); + serialize(outbuf, outmsg); + + if ((numbytes = sendto(sockfd, outbuf, buflen, 0, p->ai_addr, p->ai_addrlen)) == -1) { + perror("much error while sending"); + return -42; + } + nanosleep(&tim, NULL); + } + + freeaddrinfo(servinfo); + + close(sockfd); + + return 0; +} + + +// lauschangriff: +// einfach mal in den äther horchen und alle messages rausnehmen die wo da gibt. +// +int run_client(const struct prog_info *pinfo, void (*framecallback)(const struct message *, const struct prog_info *) ) { + + struct addrinfo hints, *servinfo; + char portbuf[6]; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // IPv4 + hints.ai_socktype = SOCK_DGRAM; // UDP + hints.ai_flags = AI_PASSIVE; + + sprintf(portbuf, "%d", pinfo->port); + + int rv; + if ((rv = getaddrinfo(NULL, portbuf, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + printf("got local address\n"); + + struct addrinfo *info; + int sockfd; + // mal drin lassen: falls die ip der gegenstelle relevant werden sollte: char s[INET6_ADDRSTRLEN]; + for (info = servinfo; info != NULL; info = info->ai_next) { + if ((sockfd = socket(info->ai_family, info->ai_socktype, info->ai_protocol)) == -1) { + perror("very socket error"); + continue; + } + + if (bind(sockfd, info->ai_addr, info->ai_addrlen) == -1) { + perror("much bind error"); + continue; + } + + break; + } + if (!info) { + fprintf(stderr, "many unbound\n"); + return 2; + } + printf("so check!\n"); + + freeaddrinfo(servinfo); // free whole list + + struct sockaddr_storage their_addr; + socklen_t addr_len = sizeof their_addr; + int numbytes; + char buf[10000]; + do { + if ((numbytes = recvfrom(sockfd, buf, 9999 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { + perror("recvfrom"); + exit(1); + } + + //printf("listener: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s)); + //printf("listener: packet is %d bytes long\n", numbytes); + //buf[numbytes] = '\0'; + //printf("listener: packet contains \"%s\"\n", buf); + + struct message *msg = (struct message *)malloc(sizeof(struct message)); + deserialize(msg, buf); + + framecallback(msg, pinfo); + + } while (strncmp(buf, "much exit", 10000)); + + close(sockfd); + + return 0; +} diff --git a/netsl/src/net.h b/netsl/src/net.h new file mode 100644 index 0000000..f2546e9 --- /dev/null +++ b/netsl/src/net.h @@ -0,0 +1,13 @@ +#ifndef __NET +#define __NET + +#include // struct sockaddr +#include "misc.h" // prog_info +#include "msg.h" // message serialization +#include "display.h" // callback + +int run_server(const struct prog_info *pinfo, char *img, int w, int h, int frms); +int run_client(const struct prog_info *pinfo,void(*framecallback)(const struct message *, const struct prog_info *)); + +#endif +