From a57c6bed8f6ab7d0f4355190c0cff7cd913da6a0 Mon Sep 17 00:00:00 2001 From: FreeArtMan Date: Tue, 9 Dec 2014 10:31:37 +0900 Subject: New planned functionality. Menuconfig support. Simple captcha. --- Kconfig | 60 +++++++++ Makefile | 10 +- articles.c | 7 +- articles.h | 2 + bbsconfig.c | 1 + bbsconfig.h | 7 + buildinfo.h | 2 +- captcha.c | 16 +++ captcha.h | 18 +++ file_use.c | 198 ++++++++++++++++++++++++++++ file_use.h | 40 ++++++ ini.c | 181 ++++++++++++++++++++++++++ ini.h | 77 +++++++++++ inih/LICENSE.txt | 27 ++++ inih/README.txt | 5 + kconf2h/kconf2h.c | 50 ++++++++ kconf2h/kconf2h.h | 10 ++ kconf2h/kconf2h_parser.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++ kconfig.h | 7 + list.c | 180 +++++++++++++++++++++++++- list.h | 83 ++++++++++-- login.c | 3 + login.h | 6 + microbbs.c | 108 +++++++++++++++- motd.c | 6 +- motd.h | 2 + session.c | 1 + session.h | 4 + statistics.c | 1 + statistics.h | 4 + telnetd.c | 0 telnetd.h | 0 textview.c | 0 textview.h | 0 34 files changed, 1428 insertions(+), 15 deletions(-) create mode 100644 Kconfig create mode 100644 bbsconfig.c create mode 100644 bbsconfig.h create mode 100644 captcha.c create mode 100644 captcha.h create mode 100644 file_use.c create mode 100644 file_use.h create mode 100644 ini.c create mode 100644 ini.h create mode 100644 inih/LICENSE.txt create mode 100644 inih/README.txt create mode 100644 kconf2h/kconf2h.c create mode 100644 kconf2h/kconf2h.h create mode 100644 kconf2h/kconf2h_parser.c create mode 100644 kconfig.h create mode 100644 login.c create mode 100644 login.h create mode 100644 session.c create mode 100644 session.h create mode 100644 statistics.c create mode 100644 statistics.h create mode 100644 telnetd.c create mode 100644 telnetd.h create mode 100644 textview.c create mode 100644 textview.h diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..3e5af48 --- /dev/null +++ b/Kconfig @@ -0,0 +1,60 @@ +menuconfig TODO + bool "List of todo" + option todo + +if TODO +endif + +menuconfig TWIT + bool "Twit soem short messages" + option twit + default n + +if TWIT +endif + +menuconfig DOORGAMES + bool "Door games" + option doorgames + default n + +if DOORGAMES +endif + +menuconfig BOARD + bool "Messaging board" + option board + default n + +if BOARD +endif + +menuconfig LOGIN + bool "User login support" + option login + default n + +if LOGIN +endif + +menuconfig ARTICLES + bool "Read articles" + option articles + default y + +if ARTICLES +endif + +menuconfig MOTD + bool "Motd message" + option motd + default y + +if MOTD +endif + + + +config CAPTCHA + bool "Enable simple captcha" + default y diff --git a/Makefile b/Makefile index 0d61766..1ee8390 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ PROJECT=microbbs CC=gcc CFLAGS= -SOURCES=motd.c buildinfo.c sysinfo.c articles.c logs.c vote.c list.c mmm.c +SOURCES=articles.c bbsconfig.c buildinfo.c captcha.c file_use.c ini.c list.c login.c logs.c mmm.c motd.c session.c statistics.c sysinfo.c telnetd.c textview.c vote.c OBJECTS=$(SOURCES:.c=.o) BUILD_DIR=build_dir @@ -10,6 +10,14 @@ all: mkdir $(OBJECTS) $(PROJECT) mkdir: mkdir -p $(BUILD_DIR) +kconfig2h: + $(CC) -c kconf2h/kconf2h_parser.c + $(CC) kconf2h/kconf2h.c kconf2h_parser.o -o kconf2h/kconf2h + +menuconfig: kconfig2h + ./mconf Kconfig + kconf2h/kconf2h .config kconfig.h + $(PROJECT): $(SOURCES) cd ./libterm; make $(CC) $(addprefix $(BUILD_DIR)/,$(OBJECTS)) $(CFLAGS) libterm/libterm.o microbbs.c -o $(PROJECT) diff --git a/articles.c b/articles.c index cf5f40d..8b4af8d 100644 --- a/articles.c +++ b/articles.c @@ -1,5 +1,7 @@ #include "articles.h" +#ifdef CONFIG_ARTICLES + //TODO add checkout on size of art it will fix, // warn about cutted images int bbs_article( term_screen *ts, const char *fname ) @@ -26,7 +28,7 @@ int bbs_article( term_screen *ts, const char *fname ) max_y = 24; } - bbs_log_article( NULL ); + bbs_log_article( fname ); if ( fname != NULL ) { @@ -161,7 +163,6 @@ int bbs_article_list( term_screen *ts, const char *dir_name ) if ( path_node.st_mode & S_IFREG ) { llist_push( dir_list, cnct_path ); - printf("-->%s\n", cnct_path); } } } @@ -236,3 +237,5 @@ int bbs_article_list( term_screen *ts, const char *dir_name ) return ret; } + +#endif diff --git a/articles.h b/articles.h index 5f773a3..fde6dda 100644 --- a/articles.h +++ b/articles.h @@ -10,6 +10,8 @@ #include #include +#include "kconfig.h" + //part of libterm #include "libterm/term.h" #include "logs.h" diff --git a/bbsconfig.c b/bbsconfig.c new file mode 100644 index 0000000..53267b8 --- /dev/null +++ b/bbsconfig.c @@ -0,0 +1 @@ +#include "bbsconfig.h" \ No newline at end of file diff --git a/bbsconfig.h b/bbsconfig.h new file mode 100644 index 0000000..c1eb80f --- /dev/null +++ b/bbsconfig.h @@ -0,0 +1,7 @@ +#ifndef __MICROBBS_BBSCONFIG_H +#define __MICROBBS_BBSCONFIG_H + +#include +#include + +#endif \ No newline at end of file diff --git a/buildinfo.h b/buildinfo.h index 3b5964d..2d91704 100644 --- a/buildinfo.h +++ b/buildinfo.h @@ -4,7 +4,7 @@ #include #include -#define BUILD_VERSION "0.1.9" +#define BUILD_VERSION "0.2.0" #define BUILD_DATE (__DATE__) void print_build_info(); diff --git a/captcha.c b/captcha.c new file mode 100644 index 0000000..ad614be --- /dev/null +++ b/captcha.c @@ -0,0 +1,16 @@ +#include "captcha.h" + +#ifdef CONFIG_CAPTCHA + +int captcha_test1() +{ + int ret = 0; + char s[2]; + printf("Are you bot?(y/n):\n"); + fgets(s,2,stdin); + if ( s[0] == 'n' || s[0] == 'N') + ret = 1; + return ret; +} + +#endif \ No newline at end of file diff --git a/captcha.h b/captcha.h new file mode 100644 index 0000000..d294955 --- /dev/null +++ b/captcha.h @@ -0,0 +1,18 @@ +#ifndef __MICROBBS_CAPTCHA_H +#define __MICROBBS_CAPTCHA_H + +#include +#include + +#include "kconfig.h" + +//ask question if you are bot or no. In 99% cases should protect from random +//bots. +// Return: +// 0 - test not passed +// 1 - test passed +int captcha_test1(); + + + +#endif \ No newline at end of file diff --git a/file_use.c b/file_use.c new file mode 100644 index 0000000..cd816bc --- /dev/null +++ b/file_use.c @@ -0,0 +1,198 @@ +#include "file_use.h" + + +void f_file_null( f_file *f_f ) +{ + if ( f_f ) + { + f_f->fid = NULL; + f_f->flags = 0; + f_f->size = -1; + f_f->seek = -1; + } +} + +int f_file_seek( f_file *f_f, long offset, int seek ) +{ + int ret=-1; + PRINT("\n"); + if ( f_f ) + { + if ( offset < 0 ) + { + ERROR("\n"); + return -1; + } + + if ( offset > f_f->size ) + { + ERROR("\n"); + return -1; + } + + + ret = fseek( f_f->fid, offset , seek ); + PRINT("ret=%d\n",ret); + if ( ret == 0 ) + { + f_f->seek = ret; + } + else + { + ERROR("cannot seek to %d\n", offset); + return -1; + } + PRINT("ret=%d\n",ret); + } + return ret; +} + + +size_t f_file_read( f_file *f_f, size_t size, void *ptr ) +{ + size_t ret=-1; + PRINT("\n"); + if ( f_f ) + { + if ( (f_f->flags == F_FILE_READ) || + (f_f->flags == F_FILE_RW)) + { + if ( f_f->size >= f_f->seek + f_f->size ) + { + ret = fread( ptr, 1, size, f_f->fid ); + /* + if ( ret != size ) + { + ERROR("%d != %d\n", ret, size ); + return -1; + } + else + */ + if ( ret < 0 ) + { + ERROR("\n"); + return ret; + } + } else + { + ERROR("\n"); + } + } else + { + ERROR("file writable only"); + } + } + return ret; +} + + +int f_file_size( f_file *f_f ) +{ + int ret=-1; + long old_seek; + + PRINT("\n"); + if ( f_f ) + { + //could make some logic break + if ( f_f->size < 0 ) + { + old_seek = ftell( f_f->fid ); + fseek( f_f->fid, 0, SEEK_END ); + ret = ftell( f_f->fid ); + fseek( f_f->fid, old_seek, SEEK_CUR ); + } + } + return ret; +} + + +//f_file_read_bl(); + + +size_t f_file_write( f_file *f_f, size_t size, void *ptr ) +{ + PRINT("%s\n"); + if ( f_f ) + { + if ((f_f->flags == F_FILE_WRITE) || + (f_f->flags == F_FILE_RW) ) + { + ERROR("Not yet ready\n"); + } + } + +} + + +//f_file_write_bl(); + + +f_file* f_file_open( const char *fname, int flags ) +{ + f_file *ret = NULL; + + const char *f_flags_write="r"; + const char *f_flags_read="w"; + const char *f_flags_rw="r+"; + char *f_flags_tmp=NULL; + + if ( fname != NULL ) + { + ret = malloc( sizeof( f_file ) ); + if ( ret == NULL ) + { + ERROR("Cannot alloc mem\n"); + return NULL; + } + memset( ret, 0, sizeof( f_file )); + f_file_null( ret ); + switch ( flags ) + { + case F_FILE_READ: + f_flags_tmp = f_flags_read; + ret->flags = F_FILE_READ; + break; + + case F_FILE_WRITE: + f_flags_tmp = f_flags_write; + ret->flags = F_FILE_WRITE; + break; + + case F_FILE_RW: + f_flags_tmp = f_flags_rw; + ret->flags = F_FILE_RW; + break; + + default: + ERROR("Unknown flag for opening \n"); + goto exit_close_f; + } + ret->fid = fopen( fname, "r" ); + if ( ret->fid == NULL ) + { + ERROR("Cannot open file\n"); + goto exit_close_f; + } + ret->size = f_file_size( ret ); + } + return ret; + +exit_close_f: + if ( ret != NULL ) + free( ret ); + return NULL; +} + + +int f_file_close( f_file *f_f ) +{ + PRINT("\n"); + if ( f_f ) + { + fclose( f_f->fid ); + free( f_f ); + f_f = NULL; + } +} + diff --git a/file_use.h b/file_use.h new file mode 100644 index 0000000..fe7cc08 --- /dev/null +++ b/file_use.h @@ -0,0 +1,40 @@ +#ifndef __LIBUTILS_FILE_USE_H +#define __LIBUTILS_FILE_USE_H + +#include +#include +#include + +#include "debug.h" + +#define F_FILE_NONE 0 +#define F_FILE_READ 1 +#define F_FILE_WRITE 2 +#define F_FILE_RW 3 + +#define F_SEEK_CUR SEEK_CUR +#define F_SEEK_END SEEK_END +#define F_SEEK_SET SEEK_SET + +//simple file using things +typedef struct f_file +{ + FILE *fid; + int flags; + long size; + int seek; +} f_file; + +void f_file_null( f_file* ); +int f_file_seek( f_file*, long, int ); +size_t f_file_read( f_file*, size_t, void* ); +//f_file_read_bl(); +int f_file_size( f_file* ); +size_t f_file_write( f_file*, size_t, void* ); +//f_file_write_bl(); +f_file* f_file_open( const char*, int ); +int f_file_close( f_file* ); +//f_file_flush(); +//f_file_mmap(); + +#endif diff --git a/ini.c b/ini.c new file mode 100644 index 0000000..27062af --- /dev/null +++ b/ini.c @@ -0,0 +1,181 @@ +/* inih -- simple .INI file parser + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +http://code.google.com/p/inih/ + +*/ + +#include +#include +#include + +#include "ini.h" + +#if !INI_USE_STACK +#include +#endif + +#define MAX_SECTION 50 +#define MAX_NAME 50 + +/* Strip whitespace chars off end of given string, in place. Return s. */ +static char* rstrip(char* s) +{ + char* p = s + strlen(s); + while (p > s && isspace((unsigned char)(*--p))) + *p = '\0'; + return s; +} + +/* Return pointer to first non-whitespace char in given string. */ +static char* lskip(const char* s) +{ + while (*s && isspace((unsigned char)(*s))) + s++; + return (char*)s; +} + +/* Return pointer to first char c or ';' comment in given string, or pointer to + null at end of string if neither found. ';' must be prefixed by a whitespace + character to register as a comment. */ +static char* find_char_or_comment(const char* s, char c) +{ + int was_whitespace = 0; + while (*s && *s != c && !(was_whitespace && *s == ';')) { + was_whitespace = isspace((unsigned char)(*s)); + s++; + } + return (char*)s; +} + +/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ +static char* strncpy0(char* dest, const char* src, size_t size) +{ + strncpy(dest, src, size); + dest[size - 1] = '\0'; + return dest; +} + +/* See documentation in header file. */ +int ini_parse_file(FILE* file, + int (*handler)(void*, const char*, const char*, + const char*), + void* user) +{ + /* Uses a fair bit of stack (use heap instead if you need to) */ +#if INI_USE_STACK + char line[INI_MAX_LINE]; +#else + char* line; +#endif + char section[MAX_SECTION] = ""; + char prev_name[MAX_NAME] = ""; + + char* start; + char* end; + char* name; + char* value; + int lineno = 0; + int error = 0; + +#if !INI_USE_STACK + line = (char*)malloc(INI_MAX_LINE); + if (!line) { + return -2; + } +#endif + + /* Scan through file line by line */ + while (fgets(line, INI_MAX_LINE, file) != NULL) { + lineno++; + + start = line; +#if INI_ALLOW_BOM + if (lineno == 1 && (unsigned char)start[0] == 0xEF && + (unsigned char)start[1] == 0xBB && + (unsigned char)start[2] == 0xBF) { + start += 3; + } +#endif + start = lskip(rstrip(start)); + + if (*start == ';' || *start == '#') { + /* Per Python ConfigParser, allow '#' comments at start of line */ + } +#if INI_ALLOW_MULTILINE + else if (*prev_name && *start && start > line) { + /* Non-black line with leading whitespace, treat as continuation + of previous name's value (as per Python ConfigParser). */ + if (!handler(user, section, prev_name, start) && !error) + error = lineno; + } +#endif + else if (*start == '[') { + /* A "[section]" line */ + end = find_char_or_comment(start + 1, ']'); + if (*end == ']') { + *end = '\0'; + strncpy0(section, start + 1, sizeof(section)); + *prev_name = '\0'; + } + else if (!error) { + /* No ']' found on section line */ + error = lineno; + } + } + else if (*start && *start != ';') { + /* Not a comment, must be a name[=:]value pair */ + end = find_char_or_comment(start, '='); + if (*end != '=') { + end = find_char_or_comment(start, ':'); + } + if (*end == '=' || *end == ':') { + *end = '\0'; + name = rstrip(start); + value = lskip(end + 1); + end = find_char_or_comment(value, '\0'); + if (*end == ';') + *end = '\0'; + rstrip(value); + + /* Valid name[=:]value pair found, call handler */ + strncpy0(prev_name, name, sizeof(prev_name)); + if (!handler(user, section, name, value) && !error) + error = lineno; + } + else if (!error) { + /* No '=' or ':' found on name[=:]value line */ + error = lineno; + } + } + +#if INI_STOP_ON_FIRST_ERROR + if (error) + break; +#endif + } + +#if !INI_USE_STACK + free(line); +#endif + + return error; +} + +/* See documentation in header file. */ +int ini_parse(const char* filename, + int (*handler)(void*, const char*, const char*, const char*), + void* user) +{ + FILE* file; + int error; + + file = fopen(filename, "r"); + if (!file) + return -1; + error = ini_parse_file(file, handler, user); + fclose(file); + return error; +} diff --git a/ini.h b/ini.h new file mode 100644 index 0000000..5390706 --- /dev/null +++ b/ini.h @@ -0,0 +1,77 @@ +/* inih -- simple .INI file parser + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +http://code.google.com/p/inih/ + +*/ + +#ifndef __INI_H__ +#define __INI_H__ + +/* Make this header file easier to include in C++ code */ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Parse given INI-style file. May have [section]s, name=value pairs + (whitespace stripped), and comments starting with ';' (semicolon). Section + is "" if name=value pair parsed before any section heading. name:value + pairs are also supported as a concession to Python's ConfigParser. + + For each name=value pair parsed, call handler function with given user + pointer as well as section, name, and value (data only valid for duration + of handler call). Handler should return nonzero on success, zero on error. + + Returns 0 on success, line number of first error on parse error (doesn't + stop on first error), -1 on file open error, or -2 on memory allocation + error (only when INI_USE_STACK is zero). +*/ +int ini_parse(const char* filename, + int (*handler)(void* user, const char* section, + const char* name, const char* value), + void* user); + +/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't + close the file when it's finished -- the caller must do that. */ +int ini_parse_file(FILE* file, + int (*handler)(void* user, const char* section, + const char* name, const char* value), + void* user); + +/* Nonzero to allow multi-line value parsing, in the style of Python's + ConfigParser. If allowed, ini_parse() will call the handler with the same + name for each subsequent line parsed. */ +#ifndef INI_ALLOW_MULTILINE +#define INI_ALLOW_MULTILINE 1 +#endif + +/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of + the file. See http://code.google.com/p/inih/issues/detail?id=21 */ +#ifndef INI_ALLOW_BOM +#define INI_ALLOW_BOM 1 +#endif + +/* Nonzero to use stack, zero to use heap (malloc/free). */ +#ifndef INI_USE_STACK +#define INI_USE_STACK 1 +#endif + +/* Stop parsing on first error (default is to keep parsing). */ +#ifndef INI_STOP_ON_FIRST_ERROR +#define INI_STOP_ON_FIRST_ERROR 0 +#endif + +/* Maximum line length for any line in INI file. */ +#ifndef INI_MAX_LINE +#define INI_MAX_LINE 200 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __INI_H__ */ diff --git a/inih/LICENSE.txt b/inih/LICENSE.txt new file mode 100644 index 0000000..1d31de2 --- /dev/null +++ b/inih/LICENSE.txt @@ -0,0 +1,27 @@ + +The "inih" library is distributed under the New BSD license: + +Copyright (c) 2009, Brush Technology +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Brush Technology nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY BRUSH TECHNOLOGY ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BRUSH TECHNOLOGY BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/inih/README.txt b/inih/README.txt new file mode 100644 index 0000000..8e5f8b1 --- /dev/null +++ b/inih/README.txt @@ -0,0 +1,5 @@ + +inih is a simple .INI file parser written in C, released under the New BSD +license (see LICENSE.txt). Go to the project home page for more info: + +http://code.google.com/p/inih/ diff --git a/kconf2h/kconf2h.c b/kconf2h/kconf2h.c new file mode 100644 index 0000000..91ef6c7 --- /dev/null +++ b/kconf2h/kconf2h.c @@ -0,0 +1,50 @@ +#include +#include + +#include + +#include "kconf2h.h" + +int main( int argc, char **argv ) +{ + FILE *fin = NULL; + FILE *fout = NULL; + struct stat st; + + char *buf=NULL; + if ( argc == 3 ) + { + fin = fopen( argv[1], "r+" ); + fout = fopen( argv[2], "w+" ); + fseek( fin, 0, SEEK_SET ); + if ( fin && fout ) + { + if ( stat( argv[1], &st ) ) + { + goto error_exit; + } + buf = malloc( st.st_size ); memset( buf, 0, st.st_size ); + size_t r_size = fread( buf, 1, st.st_size, fin ); + if ( r_size > 0 ) + { + int ret = parse_kconf2h( buf, fout ); + printf("Kconfig file parsed %d %d bytes\n", ret, r_size ); + } else + { + printf("ERR: while reading file %s [%d]\n", argv[1], r_size); + } +error_exit: + if ( buf ) free( buf ); + fclose( fin ); + fclose( fout ); + } else + { + printf("ERR: Cannot open file\n"); + } + } else + { + printf("ERR: usage ./kconf2h [conffile] [outputheader]\n"); + return -1; + } + return 0; +} diff --git a/kconf2h/kconf2h.h b/kconf2h/kconf2h.h new file mode 100644 index 0000000..165d4cc --- /dev/null +++ b/kconf2h/kconf2h.h @@ -0,0 +1,10 @@ +#ifndef __KCONF2H_H +#define __KCONF2H_H + +#include +#include +#include + +int parse_kconf2h( const char*, FILE* ); + +#endif diff --git a/kconf2h/kconf2h_parser.c b/kconf2h/kconf2h_parser.c new file mode 100644 index 0000000..5269c14 --- /dev/null +++ b/kconf2h/kconf2h_parser.c @@ -0,0 +1,327 @@ + +#line 1 "kconf2h_parser.ragel" +#include +#include +#include +#include + +#include "kconf2h.h" + +#define TYPE_YM 1 +#define TYPE_HEX 2 +#define TYPE_STR 3 +#define TYPE_DEC 4 + +char *new_string( const char *start, const char *end ) +{ + int str_s = end-start+1; + char *new_str=malloc( str_s+1 ); + memcpy( new_str, start, str_s ); + if ( new_str != NULL ) + new_str[str_s]=0x0; + return new_str; +} + +int o_head_def( FILE *f, int type, const char *s_define, const char *e_define, + const char *s_value, const char *e_value ) +{ + if ( f != NULL ) + { + if ( (s_define != NULL) && (e_define != NULL) && (s_define <= e_define) && + (s_value != NULL) && ( e_value != NULL ) && ( s_value <= e_value )) + { + char *def = new_string( s_define, e_define ); + char *val = NULL; + //printf( "%s\n", def ); + fprintf( f, "#define %s", def ); + free( def ); + + if ( type != TYPE_YM ) + { + val = new_string( s_value, e_value ); + fprintf( f, " %s", val ); + free( val ); + } + /* + switch ( type ) + { + case TYPE_HEX: + fprintf( f, " %s", val ); + break; + case TYPE_STR: + fprintf( f, " %s", val ); + break; + case TYPE_DEC: + fprintf( f, " %s", val ); + break; + default: + printf("Unknown Kconfig type %d\n", type); + } + */ + + fprintf( f, "\n" ); + return 1; + } + } + return 0; +} + + +#line 71 "kconf2h_parser.c" +static const char _k2h_actions[] = { + 0, 1, 0, 1, 2, 1, 7, 1, + 11, 2, 9, 1, 4, 3, 8, 10, + 11, 4, 4, 8, 10, 11, 4, 5, + 8, 10, 11, 4, 6, 8, 10, 11 + +}; + +static const char _k2h_key_offsets[] = { + 0, 0, 3, 6, 7, 8, 9, 10, + 11, 12, 17, 23, 30, 33, 37, 39, + 42, 46, 52, 59, 60 +}; + +static const char _k2h_trans_keys[] = { + 10, 35, 67, 10, 32, 126, 79, 78, + 70, 73, 71, 95, 95, 48, 57, 65, + 90, 61, 95, 48, 57, 65, 90, 34, + 45, 48, 109, 121, 49, 57, 34, 32, + 126, 10, 34, 32, 126, 48, 57, 10, + 48, 57, 10, 120, 48, 57, 48, 57, + 65, 70, 97, 102, 10, 48, 57, 65, + 70, 97, 102, 10, 10, 35, 67, 0 +}; + +static const char _k2h_single_lengths[] = { + 0, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 5, 1, 2, 0, 1, + 2, 0, 1, 1, 3 +}; + +static const char _k2h_range_lengths[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 0, 0 +}; + +static const char _k2h_index_offsets[] = { + 0, 0, 4, 7, 9, 11, 13, 15, + 17, 19, 23, 28, 35, 38, 42, 44, + 47, 51, 55, 60, 62 +}; + +static const char _k2h_indicies[] = { + 0, 2, 3, 1, 0, 4, 1, 5, + 1, 6, 1, 7, 1, 8, 1, 9, + 1, 10, 1, 11, 11, 11, 1, 12, + 11, 11, 11, 1, 13, 14, 15, 17, + 17, 16, 1, 19, 18, 1, 20, 19, + 18, 1, 21, 1, 22, 21, 1, 22, + 23, 21, 1, 24, 24, 24, 1, 25, + 24, 24, 24, 1, 26, 1, 0, 2, + 3, 1, 0 +}; + +static const char _k2h_trans_targs[] = { + 20, 0, 2, 3, 2, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 14, 16, + 15, 19, 12, 13, 20, 15, 20, 17, + 18, 20, 20 +}; + +static const char _k2h_trans_actions[] = { + 7, 0, 1, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 5, 5, 5, + 5, 5, 0, 0, 22, 0, 17, 0, + 0, 27, 12 +}; + +static const int k2h_start = 1; +static const int k2h_first_final = 20; +static const int k2h_error = 0; + +static const int k2h_en_main = 1; + + +#line 87 "kconf2h_parser.ragel" + + +int parse_kconf2h( const char *str, FILE *outf ) +{ + + + + static uint8_t cs; + const int stacksize = 10; + int res=0, *top=0, *stack=NULL; + stack = malloc( sizeof(stack)*stacksize ); + char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL; + + /* + variables used in state machine + */ + char *token_s=NULL, *token_e=NULL; + char *value_s=NULL, *value_e=NULL; + int token_type=0; + fprintf( outf, "#ifndef __KCONFIG_H\n" ); + fprintf( outf, "#define __KCONFIG_H\n" ); + + +#line 172 "kconf2h_parser.c" + { + cs = k2h_start; + } + +#line 110 "kconf2h_parser.ragel" + +#line 179 "kconf2h_parser.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _k2h_trans_keys + _k2h_key_offsets[cs]; + _trans = _k2h_index_offsets[cs]; + + _klen = _k2h_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _k2h_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _k2h_indicies[_trans]; + cs = _k2h_trans_targs[_trans]; + + if ( _k2h_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _k2h_actions + _k2h_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +#line 72 "kconf2h_parser.ragel" + {} + break; + case 1: +#line 73 "kconf2h_parser.ragel" + {token_s = p;} + break; + case 2: +#line 73 "kconf2h_parser.ragel" + {token_e = p-1;} + break; + case 3: +#line 76 "kconf2h_parser.ragel" + {token_type=TYPE_YM;} + break; + case 4: +#line 77 "kconf2h_parser.ragel" + {token_type=TYPE_DEC;} + break; + case 5: +#line 78 "kconf2h_parser.ragel" + {token_type=TYPE_STR;} + break; + case 6: +#line 79 "kconf2h_parser.ragel" + {token_type=TYPE_HEX;} + break; + case 7: +#line 79 "kconf2h_parser.ragel" + {value_s = p;} + break; + case 8: +#line 79 "kconf2h_parser.ragel" + {value_e = p-1;} + break; + case 9: +#line 80 "kconf2h_parser.ragel" + {} + break; + case 10: +#line 80 "kconf2h_parser.ragel" + { o_head_def( outf, token_type, token_s, token_e, value_s, value_e ); } + break; + case 11: +#line 82 "kconf2h_parser.ragel" + {} + break; +#line 301 "kconf2h_parser.c" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +#line 111 "kconf2h_parser.ragel" + + if ( cs == k2h_error ) + { + printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p); + res = -1; + } + + fprintf( outf, "#endif\n" ); + + return res; +} + + + diff --git a/kconfig.h b/kconfig.h new file mode 100644 index 0000000..bb80b88 --- /dev/null +++ b/kconfig.h @@ -0,0 +1,7 @@ +#ifndef __KCONFIG_H +#define __KCONFIG_H +#define CONFIG_TODO +#define CONFIG_ARTICLES +#define CONFIG_MOTD +#define CONFIG_CAPTCHA +#endif diff --git a/list.c b/list.c index 83655cd..7e7f732 100644 --- a/list.c +++ b/list.c @@ -39,8 +39,9 @@ int llist_index( struct List *list, void *ptr ) } -void llist_reverse( struct List **list ) +void llist_reverse( struct List *list ) { + ERROR("\n"); //abort(0); } @@ -108,6 +109,67 @@ void llist_push( struct List *list, void *ptr ) } +void* llist_removen( struct List *l, struct ListNode *ln ) +{ + ListNode *ret=NULL; + ListNode *iter = l->first; + ListNode *prev_iter = NULL; + + if ( iter == NULL ) + goto result_ready; + + while ( iter->next != NULL ) + { + if ( iter == ln ) + { + break; + } + prev_iter = iter; + iter = iter->next; + } + ret = iter; + iter = NULL; //dont use iter anymore pls + + if ( ret != NULL ) + { + //if first element of list + //the prev=NULL + if ( prev_iter == NULL ) + { + //if only one element in da list? + + if ( l->first == l->last ) + { + l->first = NULL; + l->last = NULL; + } else + //if more then one element + { + l->first = l->first->next; + } + ret->next = NULL; + goto result_ready; + } + + //if last element of the list + if ( ret == l->last ) + { + prev_iter->next = NULL; + l->last = prev_iter; + goto result_ready; + } + + //if in da middle + prev_iter->next = ((ListNode *)ret)->next; + ((ListNode *)ret)->next = NULL; + + + } + +result_ready: + return ret; +} + void llist_free( struct List *list ) { @@ -137,6 +199,122 @@ void llist_free( struct List *list ) void llist_freen( struct ListNode *node ) { + ERROR("\n"); +} + + + +void llist_sortn( struct List *list, clb_llist_cmp clb_cmp) +{ + int print_list( List *ln ) + { + if ( ln == NULL ) return; + char *ptr=NULL; + ListNode *l = ln->first; + + while ( l != NULL ) + { + ptr = l->val; + printf("%s", ptr); + if ( l->next != NULL ) + { + printf("(->%s) ",(char*)l->next->val ); + } + //printf("\n"); + l = l->next; + } + printf("\n"); + + return 1; + } + + int print_node( ListNode *n ) + { + if ( n == NULL ) return; + while ( n != NULL ) + { + printf("%s ", (char*)n->val); + n = n->next; + } + printf("\n"); + } + + + //creat new empty list and add all elements sorted + struct ListNode *sorted=NULL, *last=NULL, *get=NULL; + + get = llist_removen( list, list->first ); + sorted = get; + get = llist_removen( list, list->first ); + + while ( get != NULL ) + { + //add to empty in sorted like place + struct ListNode *iter = sorted; + struct ListNode *prev_iter = malloc( sizeof(struct ListNode)); + memset( prev_iter, 0, sizeof(struct ListNode)); + prev_iter->next = iter; + while ( iter != NULL ) + { + //there could be that no empty element in da list + if ( get == NULL ) break; + if ( clb_cmp( iter->val, get->val ) >= 0 ) + { + //add to sorted list end if everything is ok + if ( iter->next == NULL ) + { + iter->next = get; + break; + } + } else + { + prev_iter->next = get; + prev_iter = get; + get->next = iter; + if ( iter == sorted ) + { + sorted = prev_iter; + } + iter = prev_iter; + + break; + } + prev_iter = iter; + iter = iter->next; + } + get = llist_removen( list, list->first ); + } + list->first = sorted; +} + +int llist_save( struct List *l, clb_llist_save clb_save ) +{ + int ret=0, frc=0; + if ( l == NULL ) return ret; + if ( clb_save == NULL ) return ret; + + /* + struct ListNode *iter = llist_first( l ); + + while ( iter != NULL ) + { + clb_save( ); + iter = iter->next; + } + */ + frc = clb_save( "/tmp/binlist.txt", l ); + if ( frc != 0) + ret = -1; + return ret; } +struct List* llist_load( clb_llist_load clb_load, const char *fname ) +{ + int ret = 0; + struct List *loaded = NULL; + + ret = clb_load( (char *)fname, (void **)loaded ); + + return loaded; +} diff --git a/list.h b/list.h index c443430..94794f0 100644 --- a/list.h +++ b/list.h @@ -10,42 +10,102 @@ //use stack memallocation features. need to make some changes in api +//!TODO give for_each macros that can be used +//!TODO add insert element in list for sorting stuff +//!TODO save/load could be just void* list->val that to save, sequently + + +//when need to compare 2 nodes values with are pointers on anything +// return: +// -1 (<) void 1 is less then void 2 +// 0 (=) void 1 is equal to void 2 +// 1 (>) void 1 is bigger then void 2 +typedef int (*clb_llist_cmp)(void *, void *); + +//when need to free whole list and also values of list with are just pointer +//to anything +// param void* - list->val +typedef int (*clb_llist_free)(void *); + +//load and save data to file if possible +//return +// 0 - everything is ok +// non-zero - something went wrong +// can put different errors that you whant +//param +//void* - string where to save, or how to save +//void* - linked list that need to save +typedef int (*clb_llist_save)(void *, void *); +//return +// non-zero - some error happened +// 0 - everything is ok +//param +//void* - string from where to load +//void* - list where to save +typedef int (*clb_llist_load)(void *, void **); typedef struct ListNode { struct ListNode *next; - void *val; + void *val; } ListNode; typedef struct List { - int count; + int count; ListNode *first; ListNode *last; } List; +typedef struct ListManager +{ + List *list; + int sorted; //auto sort if needed + int mode; // read only + char *name; // list name + clb_llist_cmp *cmp; + clb_llist_free *free; + clb_llist_save *save; + clb_llist_load *load; +} ListManager; + + + + struct List* llist_new(); struct ListNode* llist_newn( void* ); +struct ListManager* llist_newm(); //#define __LLIST_NEW() //#define __LLIST_NEWN() int llist_length( struct List* ); int llist_index( struct List*, void* ); //llist_find( struct List ); -//find by pointer -//find by value -void llist_reverse( struct List** ); +//!find by pointer +//!find by value + +void llist_reverse( struct List* ); + +//void llist_append( struct List*, void* ); -void llist_append( struct List*, void* ); void llist_appendn( struct List**, void*, struct ListNode* ); //#define __LIST_APPEND() +// get one element from list and erease it from list void* llist_pop( struct List* ); +//add at the end one element void llist_push( struct List*, void* ); +//remove node from list and return value of element +//void* llist_remove( struct List*, struct ListNode* ); +void* llist_removen( struct List*, struct ListNode* ); +//delete one element from the list +//void llist_delete( struct List*, void*); + void llist_free( struct List* ); void llist_freen( struct ListNode* ); + //void llist_merge( struct List**, struct List* ); //void llist_compare( struct List //void llist_split( struct List*, @@ -53,8 +113,12 @@ void llist_freen( struct ListNode* ); //void llist_splitp( struct List*, void* //void llist_splitc( struct List*, void (*)(void*) //void llist_sort( -//sort by pointer -//sort by value +//!sort by pointer +//!sort by val value, need compare callback +void llist_sortn( struct List*, clb_llist_cmp ); + +int llist_save( struct List*, clb_llist_save ); +struct List* llist_load( clb_llist_load, const char* ); #define llist_first(A) ((A)->first) #define llist_last(A) ((A)->last) @@ -66,4 +130,7 @@ void llist_freen( struct ListNode* ); //#define llist_isfirstn(A) () //#define llist_getfirstn(A) ((A)) //#define llist_getlastn(A) () + + + #endif diff --git a/login.c b/login.c new file mode 100644 index 0000000..c43e9bb --- /dev/null +++ b/login.c @@ -0,0 +1,3 @@ +#include "login.h" + + diff --git a/login.h b/login.h new file mode 100644 index 0000000..dbfa63c --- /dev/null +++ b/login.h @@ -0,0 +1,6 @@ +#ifndef __MICROBBS_LOGIN_H +#define __MICROBBS_LOGIN_H + + + +#endif \ No newline at end of file diff --git a/microbbs.c b/microbbs.c index 6a6c098..8387cb8 100644 --- a/microbbs.c +++ b/microbbs.c @@ -1,6 +1,7 @@ #include #include +#include "kconfig.h" #include "logs.h" #include "motd.h" #include "libterm/term.h" @@ -16,36 +17,139 @@ int main( int argc, char **argv ) term_init_data( &ts ); //printf("%d %d\n", ts.term_col, ts.term_row); + //lunch captcha and try to detect if its random bot +#ifdef CONFIG_CAPTCHA + if ( captcha_test1() != 1) + return 1; +#endif + //write to log that some user have accesed bbs + //too much fake stuff comes to log //bbs_log( NULL ); //write to default place +#ifdef CONFIG_MOTD bbs_login_motd( &ts, "art/motd.txt" ); print_build_info(); +#endif + while ( strncmp( str, "q", 1 ) && strncmp( str, "Q", 1 ) ) { - printf("(M)otd (Q)uit (S)ysinfo (A)rticles: "); + #ifdef CONFIG_MOTD + printf("(M)otd "); + #endif + + #ifdef CONFIG_ARTICLES + printf("(A)rticles "); + #endif + + #ifdef CONFIG_DOORGAMES + printf("(D)oor games "); + #endif + + #ifdef CONFIG_TWIT + printf("(T)wit "); + #endif + + #ifdef CONFIG_BOARD + printf("(B)oard "); + #endif + + #ifdef CONFIG_LOGIN + printf("(L)ogin "); + #endif + + #ifdef CONFIG_TODO + printf("T(o)do "); + #endif + printf("(Q)uit (S)ysinfo Mesa(G)es: "); ret_len = getline( &str, &str_size, stdin ); if ( ret_len > 0) { switch ( str[0] ) { + //------------------------------------------------------------------ + #ifdef CONFIG_MOTD case 'm': case 'M': { bbs_login_motd( &ts, "art/motd.txt" ); } break; + #endif case 's': case 'S': { bbs_sysinfo( &ts ); } break; + + //------------------------------------------------------------------ + #ifdef CONFIG_ARTICLES case 'a': case 'A': { bbs_article_list( &ts, "./article/" ); } break; + #endif + + //------------------------------------------------------------------ + #ifdef CONFIG_TWIT + case 't': + case 'T': + { + printf("Twitter like\n"); + } + break; + #endif + + //------------------------------------------------------------------ + #ifdef CONFIG_DOORGAMES + case 'd': + case 'D': + { + printf("Door games\n"); + } + break; + #endif + + case 'g': + case 'G': + { + printf("Messages\n"); + } + break; + + //------------------------------------------------------------------ + #ifdef CONFIG_BOARD + case 'b': + case 'B': + { + printf("Board\n"); + } + break; + #endif + + + //------------------------------------------------------------------ + #ifdef CONFIG_LOGIN + case 'l': + case 'L': + { + printf("Login?\n"); + } + break; + #endif + + //------------------------------------------------------------------ + #ifdef CONFIG_TODO + case 'o': + case 'O': + { + printf("Todo list\n"); + } + break; + #endif + case 'q': case 'Q': bbs_log_quit( NULL ); @@ -55,6 +159,8 @@ int main( int argc, char **argv ) } } } +#ifdef CONFIG_MOTD bbs_quit_motd( &ts, "art/quit.txt" ); +#endif return 0; } diff --git a/motd.c b/motd.c index ce68f77..8d11b3f 100644 --- a/motd.c +++ b/motd.c @@ -1,5 +1,7 @@ #include "motd.h" +#ifdef CONFIG_MOTD + //TODO merge 2 functions in one proper //TODO complcations with libterm int bbs_login_motd( term_screen *ts, const char *fname ) @@ -100,4 +102,6 @@ int bbs_quit_motd( term_screen *ts, const char *fname ) //printf("%d %d %d\n",y,posy,ts->term_row); return 0; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/motd.h b/motd.h index e64d06c..5837645 100644 --- a/motd.h +++ b/motd.h @@ -5,6 +5,8 @@ #include #include +#include "kconfig.h" + #include "libterm/print_utils.h" #include "libterm/term.h" diff --git a/session.c b/session.c new file mode 100644 index 0000000..ca88985 --- /dev/null +++ b/session.c @@ -0,0 +1 @@ +#include "session.h" \ No newline at end of file diff --git a/session.h b/session.h new file mode 100644 index 0000000..e91c679 --- /dev/null +++ b/session.h @@ -0,0 +1,4 @@ +#ifndef __MICROBBS_SESSION_H +#define __MICROBBS_SESSION_H + +#endif \ No newline at end of file diff --git a/statistics.c b/statistics.c new file mode 100644 index 0000000..3e0ff33 --- /dev/null +++ b/statistics.c @@ -0,0 +1 @@ +#include "statistics.h" \ No newline at end of file diff --git a/statistics.h b/statistics.h new file mode 100644 index 0000000..a91e988 --- /dev/null +++ b/statistics.h @@ -0,0 +1,4 @@ +#ifndef __MICROBBS_STATISTICS_H +#define __MICROBBS_STATISTICS_H + +#endif \ No newline at end of file diff --git a/telnetd.c b/telnetd.c new file mode 100644 index 0000000..e69de29 diff --git a/telnetd.h b/telnetd.h new file mode 100644 index 0000000..e69de29 diff --git a/textview.c b/textview.c new file mode 100644 index 0000000..e69de29 diff --git a/textview.h b/textview.h new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3