summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--art/motd.txt24
-rw-r--r--article/post1.txt116
-rw-r--r--articles.c80
-rw-r--r--articles.h11
-rw-r--r--buildinfo.c9
-rw-r--r--buildinfo.h13
-rw-r--r--libterm/Makefile6
-rw-r--r--libterm/print_utils.c122
-rw-r--r--libterm/print_utils.h13
-rw-r--r--libterm/screen_modes.c3
-rw-r--r--libterm/screen_modes.h15
-rw-r--r--libterm/term.c54
-rw-r--r--libterm/term.h22
-rw-r--r--microbbs.c51
-rw-r--r--motd.c52
-rw-r--r--motd.h16
-rw-r--r--sysinfo.c11
-rw-r--r--sysinfo.h8
19 files changed, 634 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e130cfe
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+make:
+ cd ./libterm; make
+ gcc -c motd.c
+ gcc -c microbbs.c
+ gcc -c buildinfo.c
+ gcc -c sysinfo.c
+ gcc -c articles.c
+ gcc buildinfo.o motd.o microbbs.o sysinfo.o articles.o libterm/libterm.o -o microbbs
diff --git a/art/motd.txt b/art/motd.txt
new file mode 100644
index 0000000..7eb0376
--- /dev/null
+++ b/art/motd.txt
@@ -0,0 +1,24 @@
+ _ ____ ____ _____
+ (_) | _ \| _ \ / ____|
+ _ __ ___ _ ___ _ __ ___ | |_) | |_) | (___
+ | '_ ` _ \| |/ __| '__/ _ \| _ <| _ < \___ \
+ | | | | | | | (__| | | (_) | |_) | |_) |____) |
+ |_| |_|_|_|_|\___|_| \___/|____/|____/|_____/
+ | | | |
+ | |__ | |__ ___
+ | '_ \| '_ \/ __|
+ | |_) | |_) \__ \_
+ |_.__/|_.__/|___(_)_
+ | (_)
+ ___ ___ __| |_ _ __ __ _
+ / __/ _ \ / _` | | '_ \ / _` |
+ | (_| (_) | (_| | | | | | (_| |_
+ \___\___/ \__,_|_|_| |_|\__, (_) _
+ | | | __/ | | |
+ __ _| | | _____ |___/ __| | ___ _ __ __ _
+ / _` | | |/ _ \ \ /\ / / _ \/ _` | / _ \| '__/ _` |
+ | (_| | | | (_) \ V V / __/ (_| || (_) | | | (_| |
+ \__,_|_|_|\___/ \_/\_/ \___|\__,_(_)___/|_| \__, |
+ __/ |
+ |___/
+Source: ftp://bbs.coding.allowed.org/microbbs.tar.gz
diff --git a/article/post1.txt b/article/post1.txt
new file mode 100644
index 0000000..d214cc7
--- /dev/null
+++ b/article/post1.txt
@@ -0,0 +1,116 @@
++------------------------------------------------------------------------------+
++ +
++------------------------------------------------------------------------------+
++ C11 _Generic +
++------------------------------------------------------------------------------+
++ +
++------------------------------------------------------------------------------+
++ INDEX +
++------------------------------------------------------------------------------+
+
+1. Intro
+2. Examples
+ 2.1. Detect type
+ 2.2. Check if types is compatible
+3. Tested
+4. Links
+5. Files
+
++------------------------------------------------------------------------------+
++ 1.INTRO +
++------------------------------------------------------------------------------+
+ In C standard c11 is supported new keyword _Generic. It add way how
+we can add at macro level decisions about variable types. And now is
+possible make some C++ like function "overloading". Here is some variants how
+to use this generic "_Generic". Now could print variables dont looking
+on its type _Generic will deal with it.
+
++------------------------------------------------------------------------------+
++ 2.EXAMPLES +
++------------------------------------------------------------------------------+
+2.1.Detect type
+
+
+
+ #define type_str(T) _Generic( (T), int: "int",\
+ long: "long",\
+ default: "Unknown type")
+
+Now we have define check for 2 types int and long. If there is some type
+undefined then choose default type and print "Unknown type". This is auto
+printf example where you can detect type and print its name. But as in page [1]
+you can add number values and compare types in simple way.
+
+ printf("Type1 %s\n", type_str('a'));
+ printf("Type2 %s\n", type_str(1));
+ printf("Type3 %s\n", type_str(1l));
+ printf("Type4 %s\n", type_str(0.0f));
+
+
+Also is possible to use generic for 2 or more types but then amount
+of declaration grows. But it means that now according to params
+we can choose best function.
+
+ #define type_str2(T1,T2) _Generic( (T1),\
+ int: _Generic((T2),int:"int int", default: "int UNK"),\
+ default: "UNK UNK" )
+
+ printf("Double Type 1 %s\n", type_str2(1,1));
+ printf("Double Type 2 %s\n", type_str2(1,0.0f));
+ printf("Double Type 3 %s\n", type_str2(.0f,.0f));
+
+
++------------------------------------------------------------------------------+
+2.2.Check if types is compatible
+
+Strange but some types could be invalid if there is const used, like
+'int' and 'const int'.
+
+ #define is_compatible(x,T) _Generic((x), T:"compatible",\
+ default: "non-compatible")
+
+Here is defined 2 types and only (int and int) and (const int and const int)
+is compatible.
+
+ int i1;
+ const int i2;
+ printf("int == int, %s\n", is_compatible(i1,int));
+ printf("const int == const int, %s\n", is_compatible(i2,const int));
+ printf("int == const int, %s\n", is_compatible(i1,const int));
+ printf("const int == int, %s\n", is_compatible(i2,int));
+
+
+
++------------------------------------------------------------------------------+
++ 3.TESTED +
++------------------------------------------------------------------------------+
+gcc-4.9.1
+clang-3.4
+
+
++------------------------------------------------------------------------------+
++ 4.LINKS +
++------------------------------------------------------------------------------+
+[1] http://www.robertgamble.net/2012/01/c11-generic-selections.html
+[2] http://en.wikipedia.org/wiki/C11_%28C_standard_revision%29
+[3] https://gcc.gnu.org/wiki/C11Status
+
++------------------------------------------------------------------------------+
++ 5.FILES +
++------------------------------------------------------------------------------+
+ex1.c - one argument generic
+ex2.c - two argument generic
+ex3.c - check for compatibility
+>base64 source.tar.gz
+H4sIAOKW01MAA+2WT2+bMBiHudafwqKaCpVLbENAStedJu1QqSd6qxRR4mzWiIn4o2Wa9t1nk5FAWZpO
+apJOe59DwOZnY8vxg71RmddFKkbW4aCaKBqbK4vGtHttsRj3wyBiPg8CizIaMt/C4wOOaUNdVkmBsTVP
+Fs/m9j3/R/Ha9Rcr30sP8w6zwGEY7Fp/RlnwZP1ZMOYWpocZTp//fP3PpUqzeibw+7KaZfLR+/IB9epk
+bqrQ+UzMpRJYltM0XyyTSj5mwlmR2MXTT0KJQqaOs3IJjif2NmCTB6QbJnVWTbCtcnXVeeYiNLq8ej0u
+R0iqCi8SqRwX/UBnpiTZNTpLc1XqW1Pkurgs9O3csU3Fmpsb85T8Lr0rH5RNnkxVMqIjrttpv+1Wt98U
+yI72nGwivV56o9jbC9vRS28se+fCN3MpRFUXCtNr9BOd+r8IHJ+O/9mJ/E9Dyrf+98O1/33w/zH4W/9X
+35diWlaF0xU/1iVirKMlr3+N9bNcfdYlc+l/BO7VV5V/U01Hh/8EtHqM9dtYK8PNHC6Si55ETYoPUmyQ
+8YeZbBAKBiHq0bmJvSXrdvY/P9X+j0LWOf/x9f6PYP8fg9fefi/1yUAo3IkZiXnfKszV7mi8sj1k6ow5
+vUyag1NjG7y1i6m7v7u13b5z7m6bWnw033zMa33QwsYDeOAd7jDSl0o3PhCQibfq+GOLgY64o+OkbfKW
+dAMAAAAAAAAAAAAAAAAAAAAAwBH4BYVOCccAKAAA
+
+
diff --git a/articles.c b/articles.c
new file mode 100644
index 0000000..b5c5ea3
--- /dev/null
+++ b/articles.c
@@ -0,0 +1,80 @@
+#include "articles.h"
+
+
+int bbs_article( term_screen *ts, const char *fname )
+{
+ int ret=-1;
+ int i=0;
+
+ FILE *f;
+ size_t str_size=0, fret=1;
+ char *str=NULL;
+ size_t in_size=0;
+ char *in_buf=NULL;
+ int max_x, max_y, ret_len;
+ int quit_loop=0;
+
+ if ( ts->mode == SCREEN_MODE_80x24 )
+ {
+ max_x = 80;
+ max_y = 24;
+ } else
+ {
+ max_x = 80;
+ max_y = 24;
+ }
+
+ if ( fname != NULL )
+ {
+ f = fopen( fname, "r" );
+ if ( f == NULL )
+ {
+ printf("Cannot open article file\n");
+ return -1;
+ }
+
+ fret = 1;
+ i = 0;
+ while ( (fret > 0) && (quit_loop == 0) )
+ {
+ fret = getline( &str, &str_size, f );
+ if ( fret > 0 )
+ {
+ printf("%s", str);
+ i += 1;
+ }
+
+ //if ( ((i > 0) && (fret == -1)) ||
+ // ((fret > 0) && (i > max_x-1)) )
+ if ( i >= max_y-1 )
+ {
+ printf("(N)ext,(Q)uit:");
+ ret_len = getline( &in_buf, &in_size, stdin );
+ if ( ret_len > 0 )
+ {
+ char ch = in_buf[0];
+ switch( ch )
+ {
+ case 'q':
+ quit_loop = 1;
+ break;
+ case 'n':
+ i = 0;
+ break;
+ default:
+ printf("Try more\n");
+ }
+ }
+ }
+
+ if ( (fret == -1) )
+ break;
+
+ }
+
+ fclose( f );
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/articles.h b/articles.h
new file mode 100644
index 0000000..4f66376
--- /dev/null
+++ b/articles.h
@@ -0,0 +1,11 @@
+#ifndef __MICROBBS_ARTICLES_H
+#define __MICROBBS_ARTICLES_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libterm/term.h"
+
+int bbs_article( term_screen*, const char* );
+
+#endif
diff --git a/buildinfo.c b/buildinfo.c
new file mode 100644
index 0000000..8b366a7
--- /dev/null
+++ b/buildinfo.c
@@ -0,0 +1,9 @@
+#include "buildinfo.h"
+
+void print_build_info()
+{
+ printf("Version:%s\n", BUILD_VERSION);
+ printf("Build:%s\n", BUILD_DATE);
+}
+
+
diff --git a/buildinfo.h b/buildinfo.h
new file mode 100644
index 0000000..d831b5e
--- /dev/null
+++ b/buildinfo.h
@@ -0,0 +1,13 @@
+#ifndef __MICROBBS_BUILDINFO_H
+#define __MICROBBS_BUILDINFO_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUILD_VERSION "0.1.4"
+#define BUILD_DATE (__DATE__)
+
+void print_build_info();
+
+#endif
+
diff --git a/libterm/Makefile b/libterm/Makefile
new file mode 100644
index 0000000..a592109
--- /dev/null
+++ b/libterm/Makefile
@@ -0,0 +1,6 @@
+
+make:
+ gcc -c term.c
+ gcc -c screen_modes.c
+ gcc -c print_utils.c
+ ld -r term.o screen_modes.o print_utils.o -o libterm.o
diff --git a/libterm/print_utils.c b/libterm/print_utils.c
new file mode 100644
index 0000000..9d4bac0
--- /dev/null
+++ b/libterm/print_utils.c
@@ -0,0 +1,122 @@
+#include "print_utils.h"
+
+int term_fprint( screen_mode_e mode, FILE *f )
+{
+ int ret=-1;
+ if (f == NULL)
+ return -1;
+
+ switch ( mode )
+ {
+ case SCREEN_MODE_80x24:
+ {
+ /*
+ const int m_x=80,m_y=24;
+ int x=0,y=0;
+ int fret=1;
+ char c;
+ while ((fret = fread(&c,1,1,f)) == 1)
+ {
+ if ( c != '\n' )
+ {
+ if ( (x < m_x) && (y < m_y) )
+ {
+ putc( c );
+ }
+ x+=1;
+ } else if ( c == '\n' )
+ {
+ x = 0;
+ y += 1;
+ }
+ }
+ */
+ }
+ break;
+ default:
+ printf("Unknown screen mode\n");
+ }
+
+ return ret;
+}
+
+
+//print data to terminal starting from x,y
+//return 0x0000yyyy0000xxxx, current stopped position
+int term_print( term_screen *ts, const char *buf, size_t size,
+ int init_x, int init_y )
+{
+ int posx=0, posy=0;
+ int ret=-1;
+ if ( buf == NULL )
+ {
+ return -1;
+ }
+
+ if ( size <= 0 )
+ {
+ return -1;
+ }
+
+ //calculate position
+ //fix for diff modes also needed
+ if ( ts->term_col > 80)
+ {
+ posx = (ts->term_col-80)/2;
+ }
+ if (ts->term_row > 24)
+ {
+ posy = (ts->term_row-24)/2;
+ }
+
+ switch ( ts->mode )
+ {
+ case SCREEN_MODE_80x24:
+ {
+ int m_x=80, m_y=24;
+ int x=init_x, y=init_y;
+ char c;
+ int i,j;
+
+
+ if (( init_x == 0 ) && (init_y == 0))
+ {
+ for (i=0; i<posx;i++)
+ printf(" ");
+ }
+
+ //draw image according to mode
+ for (i=0; i<size; i++)
+ {
+ c = buf[i];
+ if ( c == '\n' )
+ {
+ printf("\n");
+ //set
+ for (j=0; j<posx; j++)
+ printf(" ");
+ x = 0;
+ y += 1;
+ //printf("asdasdsad\n");
+ } else if ( c != '\n' )
+ {
+ if ( (x < m_x ) && (y < m_y) )
+ {
+ printf("%c",c);
+ }
+ x += 1;
+ }
+ }
+ ret = x&0x0000ffff | ((y&0x0000ffff)<<16);
+ //printf( "%08x\n", ret );
+ }
+ break;
+ default:
+ printf("Unknown mode\n");
+ }
+
+ return ret;
+}
+
+
+
diff --git a/libterm/print_utils.h b/libterm/print_utils.h
new file mode 100644
index 0000000..6665262
--- /dev/null
+++ b/libterm/print_utils.h
@@ -0,0 +1,13 @@
+#ifndef __LIBTERM_PRINT_UTILS_H
+#define __LIBTERM_PRINT_UTILS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "screen_modes.h"
+#include "term.h"
+
+int term_fprint( screen_mode_e, FILE* );
+int term_print( term_screen*, const char*, size_t, int, int );
+
+#endif
diff --git a/libterm/screen_modes.c b/libterm/screen_modes.c
new file mode 100644
index 0000000..709b332
--- /dev/null
+++ b/libterm/screen_modes.c
@@ -0,0 +1,3 @@
+#include "screen_modes.h"
+
+
diff --git a/libterm/screen_modes.h b/libterm/screen_modes.h
new file mode 100644
index 0000000..73a66a6
--- /dev/null
+++ b/libterm/screen_modes.h
@@ -0,0 +1,15 @@
+#ifndef __LIBTERM_SCREEN_MODES_H
+#define __LIBTERM_SCREEN_MODES_H
+
+typedef enum
+{
+ SCREEN_MODE_NONE=0,
+ SCREEN_MODE_80x24
+} screen_mode_e;
+
+typedef struct term_screen_mode
+{
+ screen_mode_e mode;
+} term_screen_mode;
+
+#endif
diff --git a/libterm/term.c b/libterm/term.c
new file mode 100644
index 0000000..5d2a44f
--- /dev/null
+++ b/libterm/term.c
@@ -0,0 +1,54 @@
+#include "term.h"
+
+int term_init_data( term_screen *term )
+{
+ int ret=0;
+
+ term->term_col = term_get_col();
+ if (term->term_col == -1) ret = -1;
+
+ term->term_row = term_get_row();
+ if (term->term_row == -1) ret = -1;
+
+ term->mode = SCREEN_MODE_80x24;
+
+ return ret;
+}
+
+
+int term_get_col( )
+{
+ int ret=-1;
+ int fret=-1;
+
+ struct winsize w;
+
+
+ fret = ioctl(0, TIOCGWINSZ, &w );
+ if ( fret == 0 )
+ {
+ return w.ws_col;
+ }
+
+
+ return -1;
+}
+
+
+int term_get_row( )
+{
+ int ret=-1;
+ int fret=-1;
+
+ struct winsize w;
+
+
+ fret = ioctl(0, TIOCGWINSZ, &w );
+ if ( fret == 0 )
+ {
+ return w.ws_row;
+ }
+
+ return -1;
+}
+
diff --git a/libterm/term.h b/libterm/term.h
new file mode 100644
index 0000000..4565571
--- /dev/null
+++ b/libterm/term.h
@@ -0,0 +1,22 @@
+#ifndef __LIBTERM_TERM_H
+#define __LIBTERM_TERM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+
+#include "screen_modes.h"
+
+typedef struct term_screen
+{
+ screen_mode_e mode;
+ int term_col, term_row;
+} term_screen;
+
+int term_init_data( term_screen* );
+int term_get_col( );
+int term_get_row( );
+
+#endif
diff --git a/microbbs.c b/microbbs.c
new file mode 100644
index 0000000..af22958
--- /dev/null
+++ b/microbbs.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "motd.h"
+#include "libterm/term.h"
+
+int main( int argc, char **argv )
+{
+ int ret_len;
+
+ size_t str_size=128;
+ char *str=malloc(str_size);
+
+ term_screen ts;
+ term_init_data( &ts );
+ //printf("%d %d\n", ts.term_col, ts.term_row);
+
+ bbs_motd( &ts, "art/motd.txt" );
+ print_build_info();
+ while ( strncmp( str, "q", 1 ) )
+ {
+ printf("(M)otd (Q)uit (S)ysinfo (A)rticles: ");
+ ret_len = getline( &str, &str_size, stdin );
+ if ( ret_len > 0)
+ {
+ switch ( str[0] )
+ {
+ case 'm':
+ {
+ bbs_motd( &ts, "art/motd.txt" );
+ }
+ break;
+ case 's':
+ {
+ bbs_sysinfo( &ts );
+ }
+ break;
+ case 'a':
+ {
+ bbs_article( &ts, "article/post1.txt" );
+ }
+ break;
+ case 'q':
+ break;
+ default:
+ printf("Unknow command\n");
+ }
+ }
+ }
+ return 0;
+}
diff --git a/motd.c b/motd.c
new file mode 100644
index 0000000..21d6246
--- /dev/null
+++ b/motd.c
@@ -0,0 +1,52 @@
+#include "motd.h"
+
+int bbs_motd( term_screen *ts, const char *fname )
+{
+ int posx=0, posy=0;
+ int i;
+ FILE *f = fopen( fname, "r" );
+ if ( f == NULL )
+ {
+ printf("Cannot open file %s\n", fname);
+ return -1;
+ }
+
+ int ret;
+ const int buf_size=160;
+ char buf[buf_size];
+ int x=0,y=0;
+
+ if ( ts->term_row > 24 )
+ {
+ posy = (ts->term_row-24)/2;
+ }
+ for (i=0;i<posy;i++)
+ printf("\n");
+ ret = 1;
+ while ( ret > 0 )
+ {
+ memset( buf, 0, buf_size );
+ ret = fread( buf, 1, buf_size, f );
+ if (ret > 0)
+ {
+ //printf("%d %d",x,y);
+ x = term_print( ts, buf, ret, x, y );
+ y = (x&0xffff0000)>>16;
+ x = x&0x0000ffff;
+ }
+ }
+ fclose( f );
+
+ //printf("->posy=%d y=%d x=%d\n",posy,y,x);
+ //printf("-->%d\n",ts->term_row-posy-(24-y));
+ for (i=0;i<(ts->term_row-posy-y);i++)
+ printf("\n");
+ //for (i=0;i < ts->term_row-(ts->term_row-posy-24+y);i++)
+ // printf("\n");
+ //printf("%d\n",i);
+
+ //printf("%d %d %d\n",y,posy,ts->term_row);
+
+ return 0;
+}
+
diff --git a/motd.h b/motd.h
new file mode 100644
index 0000000..f3dfd63
--- /dev/null
+++ b/motd.h
@@ -0,0 +1,16 @@
+#ifndef __MICROBBS_MOTD_H
+#define __MICROBBS_MOTD_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libterm/print_utils.h"
+#include "libterm/term.h"
+
+//get file name
+//calculate current termsize and then print motd in da middle
+int bbs_motd( term_screen*, const char* );
+
+#endif
+
diff --git a/sysinfo.c b/sysinfo.c
new file mode 100644
index 0000000..7b12e2f
--- /dev/null
+++ b/sysinfo.c
@@ -0,0 +1,11 @@
+#include "sysinfo.h"
+
+int bbs_sysinfo( term_screen *ts )
+{
+ int ret=0;
+
+ printf("BBS:MicroBBS\n");
+
+ return ret;
+}
+
diff --git a/sysinfo.h b/sysinfo.h
new file mode 100644
index 0000000..adbdec4
--- /dev/null
+++ b/sysinfo.h
@@ -0,0 +1,8 @@
+#ifndef __MICROBBS_SYSINFO_H
+#define __MICROBBS_SYSINFO_H
+
+#include "libterm/term.h"
+
+int bbs_sysinfo( term_screen* );
+
+#endif