├── WorkPath ├── bin │ └── README.md ├── var │ ├── log │ │ └── file-for-takeplace │ └── www │ │ ├── cgi-bin │ │ └── file-for-tackplace │ │ └── index.html ├── etc │ └── mini_httpd │ │ ├── mini_httpd.conf.jinja2 │ │ ├── mini_httpd.conf.Reference │ │ ├── README.md │ │ └── mini_httpd.patch ├── README.md └── lib │ └── python3.5 │ └── daemon │ ├── __init__.py │ ├── pidfile.py │ └── _metadata.py ├── bin └── file_for_tackplace.txt ├── include ├── file_for_takeplace.txt └── Makefile ├── src ├── readme@here-put-MANY.C-file.txt ├── Makefile ├── HTML-hello.c ├── hello-CGIDebugLog.c ├── py_getEnvir.cgi └── getEnvir.c ├── html ├── readme@here-put-MANY.HTML-files.txt ├── Makefile └── environment-variables.html ├── res └── readme@here-put-.json-.js-.css-etc-files.txt ├── Dev_WebServer ├── conf │ ├── .gitignore │ └── mini_httpd.conf.jinja2 ├── packages │ ├── .gitignore │ └── README.txt ├── .gitignore ├── README.md ├── Makefile └── script │ ├── build_patch.py │ └── mini_httpd_conf_patch.py ├── demo ├── download │ ├── Note_Replace-ME_as_CGIC-source-code-dir.txt │ ├── cgi_download.html │ ├── README.md │ ├── Makefile │ ├── utils.h │ ├── echo2tmnl.py │ ├── CGIDebugLogd.py │ ├── download.c │ └── utils.c ├── helloword │ ├── Note_Replace-ME_as_CGIC-source-code-dir.txt │ ├── helloworld.c │ └── Makefile ├── download_a_file │ ├── Note_Replace-ME_as_CGIC-source-code-dir.txt │ ├── cgi_download_a_file.html │ ├── Makefile │ └── download_a_file.c └── README.md ├── libraries ├── DebugLog_solution │ ├── bin │ │ └── file_for_takeplace.txt │ ├── LINUX-C_daemon │ │ ├── bin │ │ │ └── file_for_takeplace.txt │ │ ├── Makefile.inc │ │ ├── include │ │ │ ├── get_num.h │ │ │ ├── become_daemon.h │ │ │ ├── error_functions.h │ │ │ └── tlpi_hdr.h │ │ ├── lib │ │ │ ├── Build_ename.sh │ │ │ └── ename.c.inc │ │ ├── src │ │ │ ├── become_daemon.c │ │ │ ├── get_num.c │ │ │ └── error_functions.c │ │ └── Makefile │ ├── python-daemon │ │ ├── Reference │ │ │ ├── pipy@python-daemon │ │ │ │ └── python-daemon-2.1.2.tar.gz │ │ │ └── readme.md │ │ └── src_test │ │ │ └── HelloDaemon.py │ ├── Reference │ │ └── r154-r201 │ │ │ ├── echo2tmnl │ │ │ ├── setup.py │ │ │ ├── README.md │ │ │ └── echo2tmnl.py │ │ │ ├── README.md │ │ │ ├── write2ttyS0.py │ │ │ ├── testDbgLog_like_CGI.py │ │ │ └── CGIDebugLogd.py │ ├── src │ │ ├── CGIDebugLogc │ │ │ ├── Examples │ │ │ │ └── main.c │ │ │ ├── CGIDebugLogc.h │ │ │ ├── include │ │ │ │ └── web.h │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── CGIDebugLogc.c │ │ ├── CGIDebugLogd │ │ │ ├── DaemonImportTest.py │ │ │ ├── Makefile │ │ │ ├── CGIDebugLogd.py │ │ │ └── DaemonEcho2 │ │ ├── Makefile │ │ └── socketClient.py │ ├── lib │ │ ├── CGIUtils │ │ │ ├── setup.py │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── cgiutils.py │ │ ├── echo2tmnl │ │ │ ├── README.md │ │ │ ├── setup.py │ │ │ ├── Makefile │ │ │ └── echo2tmnl.py │ │ └── become_daemon │ │ │ └── Makefile │ ├── test_lib_of_become_daemon │ │ ├── Makefile │ │ └── test_become_daemon.c │ ├── Developer_Doc │ │ └── README.md │ ├── README.md │ ├── include │ │ ├── get_num.h │ │ ├── become_daemon.h │ │ ├── error_functions.h │ │ └── tlpi_hdr.h │ └── Makefile ├── cgic │ ├── cgic201.tar.gz │ ├── cgic205.tar.gz │ └── cgic207.tar.gz ├── mini_httpd-1.19.tar.gz ├── README.md ├── build_patch.py └── Makefile ├── lib ├── flate-1.4.6 │ ├── checktpl │ ├── Config.in │ ├── test.pl │ ├── Makefile │ ├── Makefile.mstc │ ├── libflate.mk │ ├── flate.h │ └── README ├── flate-2.0.1 │ ├── Makefile │ ├── flate.h │ └── README.md ├── cgic │ ├── capture.c │ ├── readme.txt │ ├── Makefile │ ├── support.txt │ ├── license.txt │ └── cgic.h └── Makefile ├── Luci-of-OpenWrt ├── luci框架代码”逻辑”流程图.pdf ├── luci框架代码”逻辑”流程图.vsdx ├── luci-web(GUI)-for-develop.pptx └── README.md ├── README.md ├── Makefile └── Doc └── Develop_Notes.md /WorkPath/bin/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/file_for_tackplace.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /include/file_for_takeplace.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WorkPath/var/log/file-for-takeplace: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/readme@here-put-MANY.C-file.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WorkPath/var/www/cgi-bin/file-for-tackplace: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /html/readme@here-put-MANY.HTML-files.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /res/readme@here-put-.json-.js-.css-etc-files.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dev_WebServer/conf/.gitignore: -------------------------------------------------------------------------------- 1 | mini_httpd.conf 2 | -------------------------------------------------------------------------------- /demo/download/Note_Replace-ME_as_CGIC-source-code-dir.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/helloword/Note_Replace-ME_as_CGIC-source-code-dir.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/bin/file_for_takeplace.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dev_WebServer/packages/.gitignore: -------------------------------------------------------------------------------- 1 | mini_httpd-1.19.tar.gz 2 | -------------------------------------------------------------------------------- /demo/download_a_file/Note_Replace-ME_as_CGIC-source-code-dir.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/bin/file_for_takeplace.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dev_WebServer/.gitignore: -------------------------------------------------------------------------------- 1 | mini_httpd-1.19.tar.gz 2 | run 3 | mini_httpd 4 | -------------------------------------------------------------------------------- /Dev_WebServer/packages/README.txt: -------------------------------------------------------------------------------- 1 | 2 | cp //Embedded-GUI-Develop/libraries/mini_httpd-1.19.tar.gz ./ 3 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/checktpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/lib/flate-1.4.6/checktpl -------------------------------------------------------------------------------- /libraries/cgic/cgic201.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/libraries/cgic/cgic201.tar.gz -------------------------------------------------------------------------------- /libraries/cgic/cgic205.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/libraries/cgic/cgic205.tar.gz -------------------------------------------------------------------------------- /libraries/cgic/cgic207.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/libraries/cgic/cgic207.tar.gz -------------------------------------------------------------------------------- /libraries/mini_httpd-1.19.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/libraries/mini_httpd-1.19.tar.gz -------------------------------------------------------------------------------- /Luci-of-OpenWrt/luci框架代码”逻辑”流程图.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/Luci-of-OpenWrt/luci框架代码”逻辑”流程图.pdf -------------------------------------------------------------------------------- /Luci-of-OpenWrt/luci框架代码”逻辑”流程图.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/Luci-of-OpenWrt/luci框架代码”逻辑”流程图.vsdx -------------------------------------------------------------------------------- /Luci-of-OpenWrt/luci-web(GUI)-for-develop.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/Luci-of-OpenWrt/luci-web(GUI)-for-develop.pptx -------------------------------------------------------------------------------- /lib/flate-1.4.6/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_LIBFLATE 2 | bool "libflate" 3 | default n 4 | help 5 | Flate is a template library used to deal with html code in CGI applications. 6 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/test.pl: -------------------------------------------------------------------------------- 1 | use CGI::TemplateHTML; 2 | 3 | my $template = new CGI::TemplateHTML(); 4 | 5 | $template->setFile("file.html"); 6 | $template->setVar("test", "toto"); 7 | 8 | $template->print; 9 | 10 | -------------------------------------------------------------------------------- /WorkPath/var/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello 6 | 7 | 8 | 9 |

Hello HTML

10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/python-daemon/Reference/pipy@python-daemon/python-daemon-2.1.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/featureoverload/Embedded-GUI-Develop/HEAD/libraries/DebugLog_solution/python-daemon/Reference/pipy@python-daemon/python-daemon-2.1.2.tar.gz -------------------------------------------------------------------------------- /lib/flate-1.4.6/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall 3 | AR = ar -r 4 | RM = rm -f 5 | 6 | all: libflate 7 | 8 | libflate: flate.o 9 | $(AR) libflate.a flate.o 10 | 11 | flate.o: flate.c 12 | $(CC) $(CFLAGS) flate.c -c -I. 13 | 14 | clean: 15 | $(RM) flate.o libflate.a checktpl 16 | -------------------------------------------------------------------------------- /lib/flate-2.0.1/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall 3 | AR = ar -r 4 | RM = rm -f 5 | 6 | all: libflate checktpl 7 | 8 | libflate: flate.o 9 | $(AR) libflate.a flate.o 10 | 11 | flate.o: flate.c 12 | $(CC) $(CFLAGS) flate.c -c -I. 13 | 14 | clean: 15 | $(RM) flate.o libflate.a checktpl 16 | -------------------------------------------------------------------------------- /Dev_WebServer/conf/mini_httpd.conf.jinja2: -------------------------------------------------------------------------------- 1 | # mini_httpd.conf 2 | # 3 | # 4 | # 5 | 6 | port=8282 7 | dir={{ var_mini_httpd_root }} ## for .html 8 | #cgipat=cgi-bin/* 9 | cgipat={{ var_mini_httpd_cgi_path }}/*.cgi ## 相对路径 10 | user=nobody 11 | pidfile={{ var_mini_httpd_pid_path }}/mini_httpd.pid 12 | logfile={{ var_mini_httpd_log_path }}/mini_httpd.log 13 | 14 | charset=UTF-8 15 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/echo2tmnl/setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | 5 | from distutils.core import setup 6 | 7 | setup ( 8 | name = 'echo2tmnl', 9 | version = '0.0.2', 10 | py_modules = ['echo2tmnl'], 11 | author = 'joseph', 12 | author_email = 'joseph.lin@aliyun.com', 13 | url = 'none', 14 | description = 'none', 15 | ) 16 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/Examples/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | 5 | #include "web.h" 6 | //#include "CGIDebugLogc.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main(int argc, char *argv[]){ 13 | 14 | char *msg = "Hello CGI Debug Log!\n"; 15 | tcdbg_printf(msg, strlen(msg)); 16 | 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /WorkPath/etc/mini_httpd/mini_httpd.conf.jinja2: -------------------------------------------------------------------------------- 1 | # mini_httpd.conf 2 | # 3 | # 4 | # 5 | 6 | port=8282 7 | dir={{ var_mini_httpd_root }} ## for .html 8 | #cgipat=cgi-bin/* 9 | cgipat={{ var_mini_httpd_cgi_path }}/*.cgi ## 相对路径 10 | user=nobody 11 | pidfile={{ var_mini_httpd_pid_path }}/mini_httpd.pid 12 | logfile={{ var_mini_httpd_log_path }}/mini_httpd.log 13 | 14 | charset=UTF-8 15 | -------------------------------------------------------------------------------- /lib/cgic/capture.c: -------------------------------------------------------------------------------- 1 | #include "cgic.h" 2 | 3 | int cgiMain() { 4 | cgiWriteEnvironment("/CHANGE/THIS/PATH/capcgi.dat"); 5 | cgiHeaderContentType("text/html"); 6 | fprintf(cgiOut, "Captured\n"); 7 | fprintf(cgiOut, "

Captured

\n"); 8 | fprintf(cgiOut, "Your form submission was captured for use in\n"); 9 | fprintf(cgiOut, "debugging CGI code.\n"); 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /WorkPath/etc/mini_httpd/mini_httpd.conf.Reference: -------------------------------------------------------------------------------- 1 | # mini_httpd.conf 2 | # 3 | # 4 | # 5 | 6 | port=8282 7 | dir=/home/josephlin/github-EbdGUIDev/WorkPath/var/www ## for .html 8 | #cgipat=cgi-bin/* 9 | cgipat=cgi-bin/*.cgi ## 相对路径 10 | user=nobody 11 | pidfile=/home/josephlin/github-EbdGUIDev/WorkPath/var/mini_httpd.pid 12 | logfile=/home/josephlin/github-EbdGUIDev/WorkPath/var/log/mini_httpd.log 13 | 14 | charset=UTF-8 15 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/echo2tmnl/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## how to use: 4 | 5 | `USER@HostName:\$ python3 setup.py sdist` 6 | 7 | `USER@HostName:\$ sudo python3 setup.py install` 8 | 9 | ```pyt 10 | $ python3 11 | Python 3.x.x 12 | >>> from echo2tmnl import echo2 13 | >>> 14 | >>> echo2("/dev/ttyS0", "heheda" ) 15 | >>> 16 | 17 | ``` 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/CGIUtils/setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | # 4 | # file name: setup.py 5 | # author : Huaxing Lin 6 | # 7 | 8 | from distutils.core import setup 9 | 10 | setup ( 11 | name = 'cgiutils', 12 | version = '1.0.0', 13 | py_modules = ['cgiutils'], 14 | author = 'joseph', 15 | author_email = 'joseph.lin@aliyun.com', 16 | url = 'none', 17 | description = 'none', 18 | ) -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/CGIDebugLogc.h: -------------------------------------------------------------------------------- 1 | /* CGIDebugLogc.h 2 | * Author : Joseph Lin 3 | * E-mail : joseph.lin@aliyun.com 4 | * 5 | * 6 | */ 7 | 8 | #ifndef __CGIDEBUGLOGC_H__ 9 | #define __CGIDEBUGLOGC_H__ 10 | 11 | 12 | 13 | int tcdbg_printf(char *message, int msg_len); 14 | int CGIdbg_printf(char *message, int msg_len); 15 | 16 | int CGIPrint(const char *fmt, ...); 17 | 18 | #endif /* no def __CGIDEBUGLOGC_H__ */ 19 | -------------------------------------------------------------------------------- /demo/helloword/helloworld.c: -------------------------------------------------------------------------------- 1 | /***************************** 2 | * 3 | ******************************/ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "cgic.h" 9 | 10 | 11 | int cgiMain(){ 12 | int ret = 0; 13 | 14 | // cgiWriteEnvironment("/CHANGE/THIS/PATH/capcgi.dat"); 15 | cgiHeaderContentType("text/html"); 16 | fprintf(cgiOut, "

Hello World

"); 17 | 18 | fflush(stdout); 19 | 20 | return ret; 21 | } 22 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/echo2tmnl/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## how to use: 4 | 5 | `USER@HostName:\$ python3 setup.py sdist` 6 | 7 | `USER@HostName:\$ sudo python3 setup.py install` 8 | 9 | ```pyt 10 | $ python3 11 | Python 3.x.x 12 | >>> from echo2tmnl import echo2 13 | >>> 14 | >>> echo2("/dev/ttyS0", "heheda" ) 15 | >>> 16 | 17 | ``` 18 | 19 | 20 | 21 | ## ToDo 22 | 23 | - [ ] touch sdist 的方式来控制避免重复编译似乎无效,所以这里去掉! 24 | 25 | -------------------------------------------------------------------------------- /html/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # 4 | # Author : Joseph Lin 5 | # E-mail : joseph.lin@aliyun.com 6 | # 7 | ### 8 | ### 9 | ### 10 | 11 | MAKE = make 12 | 13 | COPY = cp 14 | COPY_FLAGS = 15 | 16 | REMOVE = rm 17 | REMOVE_FLAGS = -f 18 | 19 | InstallPath := ../WorkPath/var/www/ 20 | 21 | .PHONY: all install clean clean_all $(InstallPath) 22 | 23 | all: 24 | @echo " nothing need to do here! \n" 25 | 26 | 27 | install: 28 | $(COPY) $(COPY_FLAGS) ./environment-variables.html $(InstallPath) 29 | 30 | clean: 31 | @echo " not achived this! \n" 32 | 33 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/CGIUtils/Makefile: -------------------------------------------------------------------------------- 1 | ### 2 | ### filename: Makefile 3 | ### function: 本Makefile 安装 CGIDebugLogd.py 等 需要的库 4 | ### 5 | 6 | .PHONY: all clean 7 | 8 | sdist: setup.py cgiutils.py 9 | python3 setup.py sdist 10 | touch sdist 11 | @echo "$'\033[0;46m----- GUIUtils lib sdist finish! -----\033[0m\n" 12 | 13 | all: 14 | python3 setup.py sdist 15 | @echo "$'\033[0;46m----- GUIUtils lib sdist finish! -----\033[0m\n" 16 | 17 | 18 | install: 19 | python3 setup.py install 20 | 21 | 22 | clean: 23 | rm -f sdist MANIFEST 24 | rm -rf dist 25 | 26 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/echo2tmnl/setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # ------ 0.0.3 ------ 4 | # 使用: `with open(_device, 'wb+',buffering=0 ) as tmnl_fd:` 5 | # 6 | # ------ 7 | # 因为使用 "wb+" 出现了: TypeError: a bytes-like object is required, not 'str' 8 | # 所以用回 'w' 9 | # ------ 10 | # 11 | 12 | from distutils.core import setup 13 | 14 | setup ( 15 | name = 'echo2tmnl', 16 | version = '0.0.1', 17 | py_modules = ['echo2tmnl'], 18 | author = 'joseph', 19 | author_email = 'joseph.lin@aliyun.com', 20 | url = 'none', 21 | description = 'none', 22 | ) 23 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/test_lib_of_become_daemon/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ### 3 | ### filename: Makefile 4 | ### 5 | ### function: 本 Makefile 将 test_become_daemon.c 编译出可执行程序 6 | ### 7 | 8 | CC=gcc 9 | RM=rm -f 10 | #VPATH=include src lib bin 11 | VPATH = ../include 12 | 13 | EXE=test 14 | 15 | FLAGS = 16 | MACRO_FLAGS += -DSTRICT_DAEMON 17 | 18 | CPPFLAGS = -I ../include 19 | CPPFLAGS += $(MACRO_FLAGS) 20 | 21 | .PHONY: all clean 22 | all: test_become_daemon 23 | 24 | test_become_daemon: ../lib/become_daemon/libbecome_daemon.a 25 | 26 | clean: 27 | rm -f test_become_daemon 28 | -------------------------------------------------------------------------------- /lib/cgic/readme.txt: -------------------------------------------------------------------------------- 1 | This is the CGIC CGI development library for C programmers. 2 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, Thomas 3 | Boutell and Boutell.Com, Inc. 4 | 5 | See the file cgic.html for complete documentation in a single 6 | HTML hypertext file to be accessed with your web browser. If you 7 | preferer, there is a plaintext version in the file cgic.txt. 8 | Or see http://www.boutell.com/cgic/ for the latest copy of 9 | the documentation. 10 | 11 | See the files license.txt and support.txt for terms of use and 12 | technical support information. 13 | 14 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/include/web.h: -------------------------------------------------------------------------------- 1 | /* web.h 2 | * 3 | * 4 | */ 5 | #ifndef __WEB_H__ 6 | #define __WEB_H__ 7 | 8 | /* ----------- CGIDebugLogc.h -------------------------*/ 9 | // const char *serverIP = "127.0.0.1"; // localhost. 10 | // const int serverPort = 21919; // the default DebugLog server port. 11 | 12 | // const int RET_SUCCESS = 0; 13 | // const int RET_FAILURE = -1; 14 | 15 | int tcdbg_printf(char *message, int msg_len); 16 | 17 | /* ------------------------------------------------------ */ 18 | 19 | 20 | #endif /* no def __WEB_H__ */ 21 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/echo2tmnl/Makefile: -------------------------------------------------------------------------------- 1 | ### 2 | ### filename: Makefile 3 | ### function: 本Makefile 安装 CGIDebugLogd.py 等 需要的库 4 | ### 5 | 6 | .PHONY: all clean install 7 | 8 | # sdist: setup.py echo2tmnl.py 9 | # python3 setup.py sdist 10 | # touch sdist 11 | # @echo "$'\033[0;46m----- echo2tmnl lib sdist finish! -----\033[0m\n" 12 | 13 | all: 14 | python3 setup.py sdist 15 | @echo "$'\033[0;46m----- echo2tmnl lib sdist finish! -----\033[0m\n" 16 | 17 | 18 | 19 | install: 20 | python3 setup.py install 21 | 22 | clean: 23 | rm -f sdist MANIFEST 24 | rm -rf dist 25 | 26 | -------------------------------------------------------------------------------- /include/Makefile: -------------------------------------------------------------------------------- 1 | # include/Makefile 2 | # 3 | # 4 | 5 | CC = gcc 6 | 7 | MAKE = make 8 | 9 | COPY = cp 10 | 11 | Libraries := ../libraries 12 | 13 | Flate := ../lib/flate 14 | CGIC := ../lib/cgic 15 | 16 | .PHONY: all clean $(Libraries) $(Flate) $(CGIC) 17 | 18 | all: cgic.h flate.h CGIDebugLogc.h 19 | 20 | # libCGIDebugLogc.a: $() 21 | cgic.h: 22 | ln -s $(CGIC)/cgic.h ./cgic.h 23 | 24 | flate.h: 25 | ln -s $(Flate)/flate.h ./flate.h 26 | 27 | CGIDebugLogc.h: 28 | ln -s $(Libraries)/DebugLog_solution/src/CGIDebugLogc/$@ $@ 29 | 30 | 31 | 32 | # clean: 33 | 34 | 35 | 36 | # clean_all: 37 | 38 | -------------------------------------------------------------------------------- /demo/helloword/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -Wall 2 | CC=gcc 3 | AR=ar 4 | RANLIB=ranlib 5 | 6 | CGIC_SOURCE := cgic207 7 | 8 | CPPFLAGS = -I $(CGIC_SOURCE) 9 | 10 | LIBS=-L./ -lcgic 11 | 12 | 13 | .PHONY: all install clean $(CGIC_SOURCE) 14 | 15 | all: libcgic.a hellowrold.cgi 16 | 17 | libcgic.a: $(CGIC_SOURCE) 18 | make --directory=$< 19 | cp $/github-Embedded-GUI-Develop 17 | $ cp ./libraries/mini_httpd ./WorkPath/bin/ 18 | $ cp ./WorkPath/etc/mini_httpd/mini_httpd.config ./WorkPath/etc/mini_httpd/mini_httpd.conf 19 | $ vim ./WorkPath/etc/mini_httpd/mini_httpd.conf 20 | $ ## 将 .conf 文件的路径改成实际环境的工作路径。 21 | $ 22 | $ cd /github_Embedded-GUI-Develop/WorkPath 23 | $ sudo ./bin/mini_httpd -C ./etc/mini_httpd/mini_httpd.conf 24 | $ ## ^ 用 root 权限运行好一点。 25 | $ 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /lib/cgic/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -Wall 2 | CC=gcc 3 | AR=ar 4 | LIBS=-L./ -lcgic 5 | 6 | all: libcgic.a cgictest.cgi capture 7 | 8 | install: libcgic.a 9 | cp libcgic.a /usr/local/lib 10 | cp cgic.h /usr/local/include 11 | @echo libcgic.a is in /usr/local/lib. cgic.h is in /usr/local/include. 12 | 13 | libcgic.a: cgic.o cgic.h 14 | rm -f libcgic.a 15 | $(AR) rc libcgic.a cgic.o 16 | 17 | #mingw32 and cygwin users: replace .cgi with .exe 18 | 19 | cgictest.cgi: cgictest.o libcgic.a 20 | gcc cgictest.o -o cgictest.cgi ${LIBS} 21 | 22 | capture: capture.o libcgic.a 23 | gcc capture.o -o capture ${LIBS} 24 | 25 | clean: 26 | rm -f *.o *.a cgictest.cgi capture 27 | 28 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogd/DaemonImportTest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | # file name: 5 | # Author : 6 | # E-mail : 7 | # 8 | ### 9 | ### 10 | """ 11 | 12 | ### 13 | ### import packages 14 | ### 15 | import os, sys, io 16 | 17 | 18 | ### 19 | ### functions define 20 | ### 21 | def foo(): 22 | pass 23 | 24 | 25 | ### 26 | ### Global variables 27 | ### 28 | doDebug = True 29 | 30 | 31 | ### 32 | ### running logical 33 | ### 34 | def main(argc, argv): 35 | for i_argv in range(argc): 36 | print("argv[{}]: {}".format(i_argv, argv[i_argv])) 37 | 38 | 39 | if __name__ == '__main__': 40 | main(len(sys.argv), sys.argv) 41 | 42 | -------------------------------------------------------------------------------- /Dev_WebServer/README.md: -------------------------------------------------------------------------------- 1 | # mini_httpd Develop 2 | 3 | 4 | 5 | ## Usage 6 | 7 | ```shell 8 | $ make init 9 | $ make 10 | $ make runserver 11 | ... 12 | 13 | $ make stopserver 14 | ``` 15 | 16 | 17 | 18 | change mini_httpd source code, 19 | 20 | ```shell 21 | $ make 22 | $ make runserver 23 | ... 24 | 25 | $ make stopserver 26 | ``` 27 | 28 | 29 | 30 | ## Test 31 | 32 | test mini_httpd server could work or not: 33 | 34 | ```shell 35 | $ cp ../src/py_getEnvir.cgi ./run/var/www/cgi-bin/ 36 | $ chmod +x run/var/www/cgi-bin/py_getEnvir.cgi 37 | $ make runserver 38 | ... 39 | 40 | ``` 41 | 42 | browser access `http://:8282/cgi-bin/py_getEnvir.cgi` 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WorkPath/etc/mini_httpd/README.md: -------------------------------------------------------------------------------- 1 | # Head 2 | 3 | reserve place 4 | 5 | *Overview* 6 | 7 | [TOC] 8 | 9 | ## Contents 10 | 11 | N/A 12 | 13 | 14 | 15 | ## 2018/Jul/22 16 | 17 | 1. 添加 mini_httpd.conf 的自动适应环境patch! 18 | 2. N/A 19 | 20 | **Detail:** 21 | 22 | *1. mini_httpd.conf patch* 23 | 24 | ​ 使用了 jinja2 库,通过模板修改 mini_httpd.conf.jinja2 并创建一个新文件 mini_httpd.conf,将修改得到的数据输出到 minni_httpd.conf 文件中。 25 | 26 | ​ 使用 jinja2 库: 27 | 28 | ```shell 29 | $ python3 -c "import jinja2" ## 测试主机环境中是否有 jinja2 库 30 | $ 31 | $ sudo apt-get install python3-pip ## 如果还未安装过 pip 的话执行这条命令。 32 | $ 33 | $ sudo pip3 install --upgrade jinja2 ## 安装 jinja2 库。 34 | $ 35 | ``` 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/python-daemon/src_test/HelloDaemon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | # 4 | # 5 | # 6 | 7 | import time 8 | from daemon import runner 9 | 10 | class App(): 11 | def __init__(self): 12 | self.stdin_path = '/dev/null' 13 | self.stdout_path = '/dev/tty' # /dev/pts/2 is the teminal running now 14 | self.stderr_path = '/dev/tty' 15 | self.pidfile_path = '/tmp/foo.pid' 16 | self.pidfile_timeout = 5 17 | 18 | def run(self): 19 | while True: 20 | print ("Hello Python-daemon!") 21 | time.sleep(10) 22 | # END class 23 | if __name__ == "__main__": 24 | app = App() 25 | daemon_runner = runner.DaemonRunner(app) 26 | daemon_runner.do_action() 27 | # END run main. 28 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/python-daemon/Reference/readme.md: -------------------------------------------------------------------------------- 1 | # Directory 2 | 3 | ## python-damon 2.1.2 ***.html 4 | 5 | **that** is the package(library) website. 6 | 7 | downloading python-daemon package from this website. 8 | 9 | (or usage: `$ sudo pip3 install python-daemon` work too.) 10 | 11 | ## How do you create a daemon in Python_-Stack Overflow*** 12 | 13 | ## @fine - ANSWER - answer.html 14 | 15 | **that** file name after *@* ANSWER-name which one has 86 votes is that how to use python-daemon package. 16 | 17 | 18 | 19 | ## python - Python3 create Daemon - Stack Overflow.html 20 | 21 | **that** is the solution of fixing some error of using python-daemon package. 22 | 23 | ​ -- it work well in Mar/31/2018 14:38 -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # src/Makefile 3 | # 4 | ### 5 | ### 6 | ### 7 | 8 | Lib := ../lib 9 | Head := ../include 10 | 11 | CGIBIN := ../WorkPath/var/www/cgi-bin 12 | 13 | CC = gcc 14 | FLAGS = -I $(Head) 15 | 16 | MAKE = make 17 | 18 | MOVE = mv 19 | MOVE_FLAGS = 20 | 21 | REMOVE = rm 22 | REMOVE_FLAGS = -f 23 | 24 | .PHONY: all clean clean_all install 25 | 26 | all: 27 | $(CC) $(FLAGS) hello-CGIDebugLog.c -L $(Lib) -lcgic -lCGIDebugLogc -lflate -o hello-CGIDebugLog.cgi 28 | $(CC) $(FLAGS) getEnvir.c -L $(Lib) -lcgic -lCGIDebugLogc -lflate -o getEnvir.cgi 29 | 30 | 31 | install: 32 | $(MOVE) $(MOVE_FLAGS) \ 33 | hello-CGIDebugLog.cgi getEnvir.cgi \ 34 | $(CGIBIN) 35 | 36 | clean: 37 | $(REMOVE) $(REMOVE_FLAGS) *.cgi 38 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/CGIUtils/README.md: -------------------------------------------------------------------------------- 1 | # Developer Document 2 | 3 | ## Introduction 4 | 5 | 使用本“库”里面的 function 来实现 python-CGI 的打印 debug log 方式! 6 | 7 | ## Uage guide 8 | 9 | ```shell 10 | $ python3 11 | ...python3 message... 12 | >>> 13 | >>> ## I am a CGI 14 | >>> from cgiutils import CGIPrint 15 | >>> 16 | >>> port = 21919 ## socket port connect to server 17 | >>> 18 | >>> CGIPrint( "this content will show on a terminal you specify with $ daemonEcho2 ", port) 19 | >>> 20 | 21 | ``` 22 | 23 | 24 | ## Install for use 25 | 26 | ```shell 27 | / $ 28 | / $ python3 setup.py sdist 29 | / $ sudo python3 setup.py install 30 | / $ 31 | ``` 32 | 33 | 34 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Developer_Doc/README.md: -------------------------------------------------------------------------------- 1 | # Developer Document 2 | 3 | 检查 Daemon 运行状态: 4 | 5 | ```shell 6 | $ ./test 7 | $ ps -C test -o "pid ppid pgid sid tty command" 8 | # PID PPID PGID SID TT COMMAND 9 | # 24731 1 24730 24730 ? ./test 10 | ``` 11 | 12 | 13 | 14 | reference: 《LINUX/UNIX系统编程手册》 15 | 16 | 17 | 18 | ## Strict Daemon 19 | 20 | 严格性的 daemon, PPID, PPID, PGID, SID 等同上, 21 | 22 | 非严格性的 daemon (只 fork 一次), 如下: 23 | 24 | ```shell 25 | $ make 26 | $ ./test 27 | $ ps -C test -o "pid ppid pgid sid tty command" 28 | # PID PPID PGID SID TT COMMAND 29 | # 27448 1 2477448 27448 ? ./test 30 | ``` 31 | 32 | 使用宏开关 STRICT_DAEMON 控制 fork 一次或两次 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/HTML-hello.c: -------------------------------------------------------------------------------- 1 | /* HTML-hello.c 2 | * 3 | * build: 4 | * gcc HTML-hello.c -o HTML-hello.cgi 5 | * 6 | */ 7 | 8 | #include /* stdout, stderr, stdin */ 9 | #include 10 | #include 11 | 12 | 13 | 14 | int main(int argc, char const *argv[]) 15 | { 16 | // HTTP head 17 | //printf("\n") 18 | 19 | printf("\n"); 20 | // HTTP contents 21 | printf("\n"); 22 | printf("\n"); 23 | printf("\n"); 24 | printf("\n"); 25 | printf("Hello\n"); 26 | printf("\n"); 27 | 28 | printf("\n"); 29 | printf("\t

Hello HTML

\n"); 30 | printf("\t

This is CGI program.

\n"); 31 | printf("\n"); 32 | printf("\n"); 33 | 34 | return 0; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/README.md: -------------------------------------------------------------------------------- 1 | # Directory Logical 2 | 3 | Branch from oldPedant/Trunk/Project/easyPSWD/KeepPSWD/Br_WebServer/v0.1.0@DebugLog... 4 | 5 | the from directory has three revision, doesn't matter, it's very basic and easy. 6 | 7 | r133, r134, r135 is those revision. 8 | 9 | 10 | 11 | ## r156 12 | 13 | ``` shell 14 | $ svn checkout -r r156 15 | $ cd 16 | $ 17 | $ cd echo2tmnl/ 18 | $ python3 setup.py sdist 19 | $ sudo python3 setup.py install 20 | ## ENTER your password 21 | $ 22 | $ cd ../ 23 | $ chmod +x CGIDebugLogd.py 24 | $ ./CGIDebugLogd.py 25 | ## usage: $ ./CGIDebugLogd.py 26 | $ ./CGIDebugLogd.py /dev/pts/0 $'hello pts/0' 27 | $ 28 | ``` 29 | 30 | 31 | 32 | ## r157 33 | 34 | -[o] socket server 功能。 -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | # 3 | ### 4 | ### 5 | ### 6 | 7 | CC = gcc 8 | 9 | object = CGIDebugLogc.o 10 | 11 | .PYTHON: all clean 12 | 13 | $(object): CGIDebugLogc.c CGIDebugLogc.h 14 | $(CC) -c $< -o $@ 15 | 16 | all: libCGIDebugLogc.a 17 | @echo "$'\033[0;46m==== build >> libCGIDebugLogc.a finish! ====\033[0m\n" 18 | 19 | AR = ar 20 | ARFLAGS = rvu 21 | libCGIDebugLogc.a: libCGIDebugLogc.a(CGIDebugLogc.o) 22 | 23 | libCGIDebugLogc.a(CGIDebugLogc.o): CGIDebugLogc.o 24 | $(AR) $(ARFLAGS) $@ $? 25 | 26 | 27 | 28 | ## use default rule 29 | tester: libCGIDebugLogc.a 30 | 31 | tester.o: Examples/main.c 32 | $(CC) -c -I include $< -o $@ 33 | 34 | 35 | clean: 36 | rm -f *.o 37 | rm -f ./Examples/*.o 38 | rm -f libCGIDebugLogc.a 39 | 40 | clean_tester: 41 | rm -f tester 42 | rm -f tester.o 43 | -------------------------------------------------------------------------------- /demo/download/cgi_download.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | download|CGI Demo 6 | 7 | 8 | 9 |

Download

10 | 11 |
14 | 15 | 16 | 17 | 18 |
19 | 21 |
22 |
23 | 24 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded GUI Develop 2 | 3 | 嵌入式 LINUX 的 Web-GUI 在 LINUX 主机上开发 - 以快速验证功能。 4 | 5 | 6 | 7 | [TOC] 8 | 9 | ## demo 10 | 11 | `demo/` 文件夹下使用 Apache2 作为 Web Server。 12 | 13 | demo 为 CGIC 开发的示例,方便熟悉使用 C 开发 CGI。 14 | 15 | 16 | 17 | ## Summary 18 | 19 | 1. 使用 mini_httpd 作为 Web Server。 20 | 2. 使用 CGIC, flate 作为 C 开发 CGI 的库。 21 | 22 | 23 | 24 | ```shell 25 | $ n/a 26 | ``` 27 | 28 | 29 |
30 | 31 | ------ 32 | 33 | 34 | # OpenWrt 之 Luci Web 开发 35 | 36 | > 出于有太多仓库不好找到目标的考虑,而且 OpenWrt 中的 Luci 本来就是在嵌入式LINUX -- 路由器中使用的,所以放在这个仓库也合适。 37 | 38 | - 本仓库单独出 [`Luci-of-OpenWrt/`](Luci-of-OpenWrt) 目录与上面原项目没有相关性,是在本 repo 中独立的存在。 39 | 40 | - 该内容并非 Luci 框架源码,而是 Luci 框架介绍和分析。 41 | 42 | - 其中或许会存在一部分代码,但是它不是 Luci 框架源码,也不是基于 Luci 框架的 web 开发源码的存放仓库。 43 | 44 | [`Luci-of-OpenWrt/`](Luci-of-OpenWrt) 是对 Luci 框架的介绍和分析用以帮助理解 Luci 框架,学习了解之后可期就可以做基于 Luci 框架的 Web 开发了。 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /demo/download_a_file/cgi_download_a_file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | download a file|CGI Demo 6 | 7 | 8 | 9 |

Download a file

10 | 11 |
14 | 15 | 16 | 17 | 18 |
19 | 21 |
22 |
23 | 24 | 31 | 32 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/become_daemon/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ### 3 | ### filename: Makefile 4 | ### 5 | ### function: 本Makefile 调用 LINUX-C_daemon/ 目录下的 Makefile, 6 | ### 并且将其编译好了的 lib/libbecome_daemon.a 拷贝到本目录下 7 | ### 8 | ### 9 | 10 | BECOME_DAEMON_PATH = ../../LINUX-C_daemon 11 | BECOME_DAEMON_PACKAGE = $(BECOME_DAEMON_PATH)/lib/libbecome_daemon.a 12 | 13 | COPY = cp 14 | COPYFLAGES = 15 | 16 | 17 | libbecome_dameon := $(BECOME_DAEMON_PATH) 18 | 19 | .PHONY: all $(libbecome_dameon) clean 20 | 21 | 22 | libbecome_daemon.a: $(libbecome_dameon) 23 | $(COPY) $(COPYFLAGES) $(BECOME_DAEMON_PACKAGE) ./ 24 | @echo "$'\033[0;46m---- finished build lib/libbecome_daemon.a ----\033[0m\n" 25 | 26 | $(libbecome_dameon): 27 | $(MAKE) --directory=$@ all 28 | 29 | 30 | #all: libbecome_daemon.a $(libbecome_dameon) 31 | 32 | clean: 33 | rm -f libbecome_daemon.a 34 | $(MAKE) --directory=$(libbecome_dameon) clean 35 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/README.md: -------------------------------------------------------------------------------- 1 | # CGIDebugLogc(库) 2 | 3 | reserve place 4 | 5 | *Overview* 6 | 7 | [TOC] 8 | 9 | ## Contents 10 | 11 | ​ N/A 12 | 13 | ## v0.0.1 基本 14 | 15 | ### 手动编译 16 | 17 | ```shell 18 | $ tree 19 | . 20 | ├── CGIDebugLogc.c 21 | ├── CGIDebugLogc.h 22 | ├── Examples 23 | │   └── main.c 24 | ├── include 25 | │   └── web.h 26 | └── Makefile 27 | $ 28 | $ gcc -c CGIDebugLogc.c -o CGIDebugLogc.o 29 | $ ar rv libCGIDebugLogc.a CGIDebugLogc.o 30 | $ 31 | $ ## compiler tester 32 | $ gcc -c -I include Examples/main.c -o tester.o 33 | $ gcc tester.o libCGIDebugLogc.a -o tester 34 | $ 35 | ``` 36 | 37 | Note: **编译出 tester 必须将 libCGIDebugLogc.a 放在 *.o 的后面!!** 38 | 39 | `$ ./tester` 运行测试前,必须确认 CGIDebugLogd.py 在后台运行。 40 | 41 | ### 自动编译(Makefile) 42 | 43 | ```shell 44 | $ make ## 编译出 libCGIDebugLogc.a 45 | $ make tester ## 编译出 tester* 测试用例。 46 | ``` 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /demo/download/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | 4 | 5 | - 加入 CGI Debug Solution - 使用 socket。 6 | 7 | 8 | 9 | 10 | 11 | ## Run Demo 12 | 13 | ```shell 14 | #### terminal 1 #### 15 | $ tty 16 | /dev/pts/1 17 | $ pwd 18 | ///demo/download/ 19 | $ ls 20 | CGIDebugLogd.py echo2tmnl.py 21 | 22 | $ python3 CGIDebugLogd.py /dev/pts/1 23 | Serving DebugLog print on port 21919... 24 | 25 | ``` 26 | 27 | ```shell 28 | #### terminal 2 #### 29 | $ ls 30 | cgi_download.html download.c 31 | utils.c utils.h 32 | Note_Replace-ME_as_CGIC-source-code-dir.txt 33 | 34 | ## Note: /\ only list the usefull files at this time(not include *.py) 35 | 36 | $ tar -xzvf ../../libraries/cgi/cgi207.tar.gz -C ./ 37 | $ make 38 | ... 39 | $ ls 40 | (new) utils.o download.cgi 41 | $ sudo make install 42 | ... 43 | ``` 44 | 45 | 使用浏览器打开 `http://localhost/cgi-bin/download.cgi` 可以测试(会看到 log 正常输出到第一个终端)。 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/write2ttyS0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # 4 | # ttyS0 不是 Serial 5 | # 6 | # pts/X 和 ttyS0 对于其它组内用户,是可写不可读的。 7 | # 同时不能使用 append 打开,因为指针位置也是不可获取的。 8 | # 9 | 10 | 11 | ### 12 | ### import pakages 13 | ### 14 | import sys 15 | 16 | ### 17 | ### global variables 18 | ## 19 | 20 | ## 21 | ## for Debug 22 | ## 23 | doThis = 2 24 | 25 | 26 | ### 27 | ### function: 28 | ### 29 | def echo2ttyS0(_str): 30 | try: 31 | with open("/dev/ttyS0", "w" ) as ttyS0_fd: 32 | print ( _str, file=ttyS0_fd ) 33 | except IOError as err: 34 | print ( "File error: " + str(err) ) 35 | #END try...except... 36 | ##fed function 37 | 38 | 39 | ### 40 | ### running logical: 41 | ### 42 | def main(): 43 | 44 | echo2ttyS0("heheda") 45 | 46 | echo2ttyS0("woaini ttyS0") 47 | 48 | sys.exit(0) 49 | ##fed func main 50 | 51 | 52 | if __name__ == "__main__": 53 | main() 54 | ##END running program. -------------------------------------------------------------------------------- /demo/download/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -Wall 2 | CC=gcc 3 | AR=ar 4 | RANLIB=ranlib 5 | 6 | CGIC_SOURCE := cgic207 7 | 8 | CPPFLAGS = -I $(CGIC_SOURCE) 9 | 10 | LIBS=-L./ -lcgic 11 | 12 | 13 | .PHONY: all install clean $(CGIC_SOURCE) 14 | 15 | 16 | all: libcgic.a download.cgi 17 | 18 | libcgic.a: $(CGIC_SOURCE) 19 | make --directory=$< 20 | cp $ 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | /**************************** 14 | * CGI Debug Log solution * 15 | ****************************/ 16 | // #define __EMBEDDED_PLATFORM /* 仅在嵌入式平台在编译运行时注释掉这一行。 */ 17 | #ifndef __EMBEDDED_PLATFORM 18 | #include 19 | 20 | #include 21 | #include /* should notice the sys/ directory. */ 22 | 23 | int tcdbg_printf(char *message, int msg_len); 24 | void CGI_Println(const char *fmt, ...); 25 | 26 | #else 27 | #define CGI_Println(fmt, arg...) do { \ 28 | FILE *fp; \ 29 | if((fp=fopen(DEVICE,"a"))==NULL)\ 30 | {\ 31 | printf("open failed "); fclose(fp);\ 32 | }\ 33 | fprintf(fp, "%s[%d]. "fmt,__FUNCTION__, __LINE__, ##arg); \ 34 | fprintf(fp, "\n"); fclose(fp);\ 35 | } while(0) 36 | #endif 37 | 38 | 39 | 40 | #define STATUS_READY 0 41 | #define ERR_DOWNLOAD_FAIL -1 42 | 43 | 44 | int handler_submit(void); 45 | 46 | 47 | 48 | #endif /* ndef __UTILS_H__ */ -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/Makefile.inc: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | 3 | TLPI_DIR = .. 4 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 5 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 6 | 7 | LINUX_LIBRT = -lrt 8 | LINUX_LIBDL = -ldl 9 | LINUX_LIBACL = -lacl 10 | LINUX_LIBCRYPT = -lcrypt 11 | LINUX_LIBCAP = -lcap 12 | 13 | # "-Wextra" is a more descriptive synonym for "-W", but only 14 | # available in more recent gcc versions 15 | 16 | # Defining _DEFAULT_SOURCE is a workaround to avoid the warnings that 17 | # would otherwise be produced when compiling code that defines _BSD_SOURCE 18 | # or _SVID_SOURCE against glibc headers in version 2.20 and later. 19 | # (The alternative would be to replace each instance of "#define _SVID_SOURCE" 20 | # or "#define _BSD_SOURCE" in the example programs with 21 | # "#define _DEFAULT_SOURCE".) 22 | 23 | IMPL_CFLAGS = -std=c99 -D_XOPEN_SOURCE=600 \ 24 | -D_DEFAULT_SOURCE \ 25 | -g -I${TLPI_INCL_DIR} \ 26 | -pedantic \ 27 | -Wall \ 28 | -W \ 29 | -Wmissing-prototypes \ 30 | -Wno-sign-compare \ 31 | -Wno-unused-parameter 32 | 33 | CFLAGS = ${IMPL_CFLAGS} 34 | 35 | IMPL_THREAD_FLAGS = -pthread 36 | 37 | IMPL_LDLIBS = ${TLPI_LIB} -lm 38 | 39 | LDLIBS = ${IMPL_LDLIBS} 40 | 41 | RM = rm -f 42 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/README.md: -------------------------------------------------------------------------------- 1 | # Develop Doc 2 | 3 | reserve place 4 | 5 | *Overview* 6 | 7 | [TOC] 8 | 9 | ## Contents 10 | N/A 11 | 12 | ## r307 更新 13 | 14 | 使用方式: 15 | 16 | ```shell 17 | $ ## checkout code! 18 | $ make 19 | $ sudo make install 20 | $ ./src/daemonEcho2 /dev/ttyS0 21 | $ 22 | ``` 23 | 24 | 25 | ## Merge r156 26 | 27 | ``` shell 28 | $ svn checkout -r r156 29 | $ cd 30 | $ 31 | $ cd echo2tmnl/ 32 | $ python3 setup.py sdist 33 | $ sudo python3 setup.py install 34 | ## ENTER your password 35 | $ 36 | $ cd ../ 37 | $ chmod +x CGIDebugLogd.py 38 | $ ./CGIDebugLogd.py 39 | ## usage: $ ./CGIDebugLogd.py 40 | $ ./CGIDebugLogd.py /dev/pts/0 $'hello pts/0' 41 | $ 42 | ``` 43 | 44 | 45 | ## Manual test daemon oled-TIMER 46 | 47 | ```shell 48 | $ make 49 | $ 50 | $ gcc -c ./bin/* runPython-oled.c -o runPython-oled.o 51 | $ 52 | $ gcc ./bin/become_daemon.o ./bin/error_functions.o ./bin/get_num.o \ 53 | ./runPython-oled.o \ 54 | -o runPython-oled.out 55 | $ 56 | $ # run oled-TIMER backend: 57 | $ ./runPython-oled.out 58 | 59 | ``` 60 | 61 | 62 | 63 | Note: this runPython-oled.c is depend on Evirnment on this RaspberryPi zero-W system. 64 | 65 | ​ there just for reference. 66 | 67 | ​ Change directory and install necessary packages. 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ### 3 | ### filename: Makefile 4 | ### 5 | ### function: 本 Makefile 将 test_become_daemon.c 编译出可执行程序 6 | ### 7 | 8 | CC=gcc 9 | RM=rm -f 10 | #VPATH=include src lib bin 11 | VPATH = ../include 12 | 13 | # EXE=daemonEcho2 CGIDebugLogd.py libCGIDebugLogc.a 14 | EXE=DaemonEcho2 CGIDebugLogd.py libCGIDebugLogc.a 15 | 16 | 17 | MACRO_FLAGS = 18 | #MACRO_FLAGS += -DSTRICT_DAEMON 19 | 20 | CPPFLAGS = -I ../include 21 | CPPFLAGS += $(MACRO_FLAGS) 22 | 23 | CGIDebugLogd := CGIDebugLogd 24 | CGIDebugLogc := CGIDebugLogc 25 | 26 | .PHONY: all clean $(CGIDebugLogc) $(CGIDebugLogd) 27 | #all: test_become_daemon 28 | #test_become_daemon: ../lib/become_daemon/libbecome_daemon.a 29 | 30 | all: $(EXE) 31 | 32 | clean: 33 | rm -f $(EXE) 34 | $(MAKE) --directory=$(CGIDebugLogc) clean 35 | $(MAKE) --directory=$(CGIDebugLogd) clean 36 | 37 | clean_all: 38 | rm -f $(EXE) 39 | $(MAKE) --directory=$(CGIDebugLogc) clean 40 | $(MAKE) --directory=$(CGIDebugLogd) clean 41 | 42 | # daemonEcho2: 43 | # $(MAKE) --directory=$(CGIDebugLogd) getdaemonEcho2 44 | DaemonEcho2: 45 | $(MAKE) --directory=$(CGIDebugLogd) getDaemonEcho2 46 | 47 | CGIDebugLogd.py: $(CGIDebugLogd)/CGIDebugLogd.py 48 | cp $< ./ 49 | 50 | 51 | libCGIDebugLogc.a: $(CGIDebugLogc)/CGIDebugLogc.o 52 | ar rvu $@ $^ 53 | $(CGIDebugLogc): 54 | $(MAKE) --directory=$@ 55 | -------------------------------------------------------------------------------- /libraries/README.md: -------------------------------------------------------------------------------- 1 | # libraries 文件夹下相关说明 2 | 3 | reserve place 4 | 5 | *Overview* 6 | 7 | [TOC] 8 | 9 | ## Contents 10 | 11 | N/A 12 | 13 | 14 | 15 | ## build out mini_httpd 16 | 17 | #### mini_httpd-1.19.tar.gz 18 | 19 | mini_httpd 的 source code, 通过 `$ make init` 解压出来给编译使用。 20 | 21 | #### build_patch.py 22 | 23 | 在 LINUX 主机上编译 mini_httpd 的source code 会提示编译错误,因为一个函数与标准库冲突(重复定义)。 24 | 25 | 运行该 patch 修改该冲突函数名,然后即可编译通过。 26 | 27 | 28 | 29 | ## cgic - for build out *libcgic.a* 30 | 31 | #### cgic/ 文件夹 32 | 33 | ​ 该文件夹下放置 cgic 的各个版本的 source code,在 lib/cgic/ 文件夹下已经放置了 cgic 2.01 版的 source code,默认情况下无需使用该目录下的压缩文件夹。 34 | 35 | 36 | 37 | ## DebugLog_solution 38 | 39 | ​ 因为 mini_httpd 是daemon 进程 (后台进程),而 mini_httpd 调用的 CGI 进程是 daemon 进程组的成员进程;mini_httpd 是组长进程。 40 | 41 | ​ 因为 LINUX 主机的进程组策略(终端策略?); 所以, CGI 进程将无法获得任何终端的描述符,即无法写数据到终端(对于有操作权限的文件,读写文件没有问题)。 42 | 43 | ​ 使用另外一个 daemon 进程作为 TCP server, CGI 进程使用 Debug Log solution 的 API,该 API 内部是 TCP client, 向该 daemon 进程发送想要显示在终端的 debug 信息。 44 | 45 | 46 | 47 | #### DebugLog_solution.zip 48 | 49 | ​ 该压缩文件内代码已经 out of date, 将不再使用。 50 | 51 | 52 | 53 | #### DebugLog_solution 文件夹 54 | 55 | ​ 该文件夹最开始由 DebugLog_solution.zip 解压出来,fix 一些小bug, 做了一些新 solution。 56 | 57 | 该 Debug Log 的 solution 使用这个文件夹中的 source code 编译。 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/CGIUtils/cgiutils.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | """ 4 | # 5 | # file name: cgiutils.py 6 | # author : Joseph Lin 7 | # E-mail : joseph.lin@aliyun.com 8 | # 9 | # ======================================= 10 | # @copyright 11 | # 12 | # ====================================== 13 | # 14 | """ 15 | 16 | ### 17 | ### import packages 18 | ### 19 | import sys 20 | import os 21 | 22 | import socket 23 | 24 | ### 25 | ### Global variables 26 | ### 27 | DebugFlag = False 28 | 29 | ### 30 | ### Functions define 31 | ### 32 | def CGIPrint( _str, _port ): 33 | ### socket client: 34 | ## reference: runoob.com/python3/python3-socket.html 35 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 36 | 37 | ## 获取本地主机名 38 | hostname = socket.gethostname() 39 | 40 | ## 设置服务器监听的端口去连接 41 | port = int(_port) ## 字符串转数字 C语言的 atoi() 42 | 43 | ## 连接服务器, 指定主机和端口 44 | s.connect((hostname, port)) 45 | 46 | sendMsg = "%s" %_str ## $ 0: 1: 2: 47 | s.send(sendMsg.encode('utf-8')) 48 | 49 | s.close() 50 | 51 | 52 | 53 | ### 54 | ### 55 | ### 56 | if __name__ == "__main__": 57 | argc = len(sys.argv) 58 | if argc != 3: 59 | print ( "usage: $ %s " % sys.argv[0], file=sys.stderr ) 60 | sys.exit(1) 61 | #fi 62 | 63 | CGIPrint(sys.argv[2], sys.argv[1]) 64 | 65 | sys.exit(0) 66 | 67 | #fi. 68 | 69 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/testDbgLog_like_CGI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # 4 | # this actually be Socket client. 5 | # the CGIDebugLogd.py is Socket Server. 6 | # 7 | # ### SOCKET PROGRAMMING ### 8 | # 9 | 10 | ### 11 | ### import pakages 12 | ### 13 | import sys 14 | 15 | import socket 16 | 17 | ### 18 | ### global variables 19 | ## 20 | 21 | ## 22 | ## for Debug 23 | ## 24 | doThis = 2 25 | 26 | 27 | ### 28 | ### function: 29 | ### 30 | def foo(): 31 | print( "foo function.", file=sys.stdout) 32 | #fed function 33 | 34 | 35 | ### 36 | ### running logical: 37 | ### 38 | def main(): 39 | argc = len(sys.argv) 40 | if argc != 4: 41 | print ( "usage: $ %s " % sys.argv[0], file=sys.stderr ) 42 | sys.exit(1) 43 | #fi 44 | 45 | foo() 46 | 47 | ### socket client: 48 | ## reference: runoob.com/python3/python3-socket.html 49 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 50 | 51 | ## 获取本地主机名 52 | hostname = socket.gethostname() 53 | 54 | ## 设置服务器监听的端口去连接 55 | port = int(sys.argv[1]) ## 字符串转数字 C语言的 atoi() 56 | 57 | ## 连接服务器, 指定主机和端口 58 | s.connect((hostname, port)) 59 | 60 | sendMsg = "%s\r\n%s" %(sys.argv[2], sys.argv[3]) 61 | s.send(sendMsg.encode('utf-8')) 62 | 63 | s.close() 64 | 65 | sys.exit(0) 66 | ##fed func main 67 | 68 | 69 | if __name__ == "__main__": 70 | main() 71 | ##END running program. 72 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/lib/echo2tmnl/echo2tmnl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # 4 | # ttyS0 不是 Serial 5 | # 6 | # pts/X 和 ttyS0 对于其它组内用户,是可写不可读的。 7 | # 同时不能使用 append 打开,因为指针位置也是不可获取的。 8 | # 9 | # --对于出错处理! 要看使用的环境。 10 | # daemon 进程调用了本 function ,基本上就是会执行 except, 11 | # print 也并不能输出给USER 看到!! 12 | # 13 | 14 | ### 15 | ### import pakages 16 | ### 17 | import sys 18 | 19 | ### 20 | ### global variables 21 | ## 22 | 23 | ## 24 | ## for Debug 25 | ## 26 | doThis = 2 27 | 28 | 29 | ### 30 | ### function: 31 | ### 32 | def echo2ttyS0(_str): 33 | try: 34 | with open("/dev/ttyS0", "w" ) as ttyS0_fd: 35 | print ( _str, file=ttyS0_fd ) 36 | except IOError as err: 37 | print ( "File error: " + str(err) ) 38 | #END try...except... 39 | ##fed function 40 | 41 | def echo2(_device, _str): 42 | try: 43 | with open(_device, "w" ) as tmnl_fd: 44 | print ( _str, file=tmnl_fd ) 45 | except IOError as err: 46 | print ( "File error: " + str(err) ) 47 | #END try...except... 48 | ##fed function 49 | 50 | 51 | ### 52 | ### running logical: 53 | ### 54 | def main(): 55 | 56 | echo2ttyS0("heheda") 57 | echo2ttyS0("woaini ttyS0") 58 | 59 | argc = len(sys.argv) 60 | if argc == 2: 61 | echo2(sys.argv[1], "heheda" ) 62 | echo2(sys.argv[1], "woaini ttyS0" ) 63 | #fi 64 | 65 | sys.exit(0) 66 | ##fed func main 67 | 68 | 69 | if __name__ == "__main__": 70 | main() 71 | ##END running program. 72 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/echo2tmnl/echo2tmnl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # 4 | # ttyS0 不是 Serial 5 | # 6 | # pts/X 和 ttyS0 对于其它组内用户,是可写不可读的。 7 | # 同时不能使用 append 打开,因为指针位置也是不可获取的。 8 | # 9 | # --对于出错处理! 要看使用的环境。 10 | # daemon 进程调用了本 function ,基本上就是会执行 except, 11 | # print 也并不能输出给USER 看到!! 12 | # 13 | 14 | ### 15 | ### import pakages 16 | ### 17 | import sys 18 | 19 | ### 20 | ### global variables 21 | ## 22 | 23 | ## 24 | ## for Debug 25 | ## 26 | doThis = 2 27 | 28 | 29 | ### 30 | ### function: 31 | ### 32 | def echo2ttyS0(_str): 33 | try: 34 | with open("/dev/ttyS0", "w" ) as ttyS0_fd: 35 | print ( _str, file=ttyS0_fd ) 36 | except IOError as err: 37 | print ( "File error: " + str(err) ) 38 | #END try...except... 39 | ##fed function 40 | 41 | def echo2(_device, _str): 42 | try: 43 | with open(_device, "w" ) as tmnl_fd: 44 | print ( _str, file=tmnl_fd ) 45 | except IOError as err: 46 | print ( "File error: " + str(err) ) 47 | #END try...except... 48 | ##fed function 49 | 50 | 51 | ### 52 | ### running logical: 53 | ### 54 | def main(): 55 | 56 | echo2ttyS0("heheda") 57 | echo2ttyS0("woaini ttyS0") 58 | 59 | argc = len(sys.argv) 60 | if argc == 2: 61 | echo2(sys.argv[1], "heheda" ) 62 | echo2(sys.argv[1], "woaini ttyS0" ) 63 | #fi 64 | 65 | sys.exit(0) 66 | ##fed func main 67 | 68 | 69 | if __name__ == "__main__": 70 | main() 71 | ##END running program. 72 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogd/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ### 3 | ### filename: Makefile 4 | ### 5 | ### function: 本 Makefile 将 test_become_daemon.c 编译出可执行程序 6 | ### 7 | 8 | CC=gcc 9 | RM=rm -f 10 | 11 | COPY=cp 12 | MOVE=mv 13 | 14 | #VPATH=include src lib bin 15 | VPATH = ../../include 16 | 17 | # EXE=daemonEcho2 18 | EXE=DaemonEcho2 19 | 20 | MACRO_FLAGS = 21 | #MACRO_FLAGS += -DSTRICT_DAEMON 22 | 23 | CPPFLAGS = -I ../../include 24 | CPPFLAGS += $(MACRO_FLAGS) 25 | 26 | 27 | .PHONY: all clean getdaemonEcho2 28 | #all: test_become_daemon 29 | #test_become_daemon: ../lib/become_daemon/libbecome_daemon.a 30 | 31 | all: $(EXE) 32 | 33 | # $(EXE): ../../lib/become_daemon/libbecome_daemon.a 34 | # $(CC) $(CPPFLAGS) daemonEcho2.c $^ -o daemonEcho2 35 | # @echo "$'\033[0;46m------ $(EXE) build finish! ------\033[0m\n" 36 | 37 | getdaemonEcho2: ../../lib/become_daemon/libbecome_daemon.a 38 | $(CC) $(CPPFLAGS) daemonEcho2.c $^ -o ../daemonEcho2 39 | @echo "$'\033[0;46m------ $(EXE) build finish! ------\033[0m\n" 40 | 41 | ## src DebugLog_solution libraries Dev 42 | getDaemonEcho2: ../../../../WorkPath/lib/python3.5/daemon 43 | $(COPY) DaemonEcho2 ../ 44 | @echo "$'\033[0;46m------ $(EXE) build finish! ------\033[0m\n" 45 | 46 | clean: 47 | ### 48 | ### usage LINUX-C_daemon 49 | ### 50 | # rm -f $(EXE) 51 | ### 52 | ### usage python-daemon 53 | ### 54 | @echo "/libraries/DebugLog_solution/src/CGIDebugLogd/ clean!\n" 55 | -------------------------------------------------------------------------------- /demo/download/echo2tmnl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # 4 | # ttyS0 不是 Serial 5 | # 6 | # pts/X 和 ttyS0 对于其它组内用户,是可写不可读的。 7 | # 同时不能使用 append 打开,因为指针位置也是不可获取的。 8 | # 9 | # --对于出错处理! 要看使用的环境。 10 | # daemon 进程调用了本 function ,基本上就是会执行 except, 11 | # print 也并不能输出给USER 看到!! 12 | # 13 | 14 | ### 15 | ### import pakages 16 | ### 17 | import sys 18 | 19 | ### 20 | ### global variables 21 | ## 22 | 23 | ## 24 | # for Debug 25 | ## 26 | doThis = 2 27 | 28 | 29 | ### 30 | # function: 31 | ### 32 | def echo2ttyS0(_str): 33 | try: 34 | with open("/dev/ttyS0", "w") as ttyS0_fd: 35 | print(_str, file=ttyS0_fd) 36 | except IOError as err: 37 | print("File error: " + str(err)) 38 | # END try...except... 39 | # fed function 40 | 41 | 42 | def echo2(_device, _str): 43 | try: 44 | with open(_device, "w") as tmnl_fd: 45 | print(_str, file=tmnl_fd) 46 | except IOError as err: 47 | print("File error: " + str(err)) 48 | # END try...except... 49 | # fed function 50 | 51 | 52 | ### 53 | # running logical: 54 | ### 55 | def main(): 56 | 57 | echo2ttyS0("heheda") 58 | echo2ttyS0("woaini ttyS0") 59 | 60 | argc = len(sys.argv) 61 | if argc == 2: 62 | echo2(sys.argv[1], "heheda") 63 | echo2(sys.argv[1], "woaini ttyS0") 64 | # fi 65 | 66 | sys.exit(0) 67 | # fed func main 68 | 69 | 70 | if __name__ == "__main__": 71 | main() 72 | # END running program. 73 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/include/get_num.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-5 */ 12 | 13 | /* get_num.h 14 | 15 | Header file for get_num.c. 16 | */ 17 | #ifndef GET_NUM_H 18 | #define GET_NUM_H 19 | 20 | #define GN_NONNEG 01 /* Value must be >= 0 */ 21 | #define GN_GT_0 02 /* Value must be > 0 */ 22 | 23 | /* By default, integers are decimal */ 24 | #define GN_ANY_BASE 0100 /* Can use any base - like strtol(3) */ 25 | #define GN_BASE_8 0200 /* Value is expressed in octal */ 26 | #define GN_BASE_16 0400 /* Value is expressed in hexadecimal */ 27 | 28 | long getLong(const char *arg, int flags, const char *name); 29 | 30 | int getInt(const char *arg, int flags, const char *name); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/include/get_num.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-5 */ 12 | 13 | /* get_num.h 14 | 15 | Header file for get_num.c. 16 | */ 17 | #ifndef GET_NUM_H 18 | #define GET_NUM_H 19 | 20 | #define GN_NONNEG 01 /* Value must be >= 0 */ 21 | #define GN_GT_0 02 /* Value must be > 0 */ 22 | 23 | /* By default, integers are decimal */ 24 | #define GN_ANY_BASE 0100 /* Can use any base - like strtol(3) */ 25 | #define GN_BASE_8 0200 /* Value is expressed in octal */ 26 | #define GN_BASE_16 0400 /* Value is expressed in hexadecimal */ 27 | 28 | long getLong(const char *arg, int flags, const char *name); 29 | 30 | int getInt(const char *arg, int flags, const char *name); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /html/environment-variables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | get Env by CGIC 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Envirnments avaible:
16 |
    17 |
  • SERVER_PORT : ##v_port##
  • 18 |
  • SERVER_NAME : ##v_serverName##
  • 19 |
  • HTTP_HOST : ##v_reqHost##
  • 20 |
  • REQUEST_METHOD : ##v_reqMethod##
  • 21 |
  • SERVER_PROTOCOL : ##v_serverProtocol##
  • 22 |
  • SERVER_SOFTWARE : ##v_serverSoftware##
  • 23 |
  • HTTP_USER_AGENT : ##v_userAgent##
  • 24 |
  • GATEWAY_INTERFACE : ##v_gatewayInterface##
  • 25 |
  • PATH : ##v_PATH##
  • 26 |
  • SCRIPT_NAME : ##v_scriptName##
  • 27 |
  • REMOTE_ADDR : ##v_remoteAddr##
  • 28 |
  • LD_LIBRARY_PATH : ##v_libPATH##
  • 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/Makefile.mstc: -------------------------------------------------------------------------------- 1 | #/******************************************************************************/ 2 | #/* 3 | #* Copyright (C) Mitrastar Communications, Corp. 4 | #* All Rights Reserved. 5 | #* 6 | #* Mitrastar Confidential; Need to Know only. 7 | #* Protected as an unpublished work. 8 | #* 9 | #* The computer program listings, specifications and documentation 10 | #* herein are the property of Mitrastar Communications, Corp. and 11 | #* shall not be reproduced, copied, disclosed, or used in whole or 12 | #* in part for any reason without the prior express written permission of 13 | #* Mitrastar Communications, Corp. 14 | #*/ 15 | #/******************************************************************************/ 16 | include ${PRODUCT_ROOT_DIR}/Project/Make.config 17 | 18 | APP_SRC_DIR := $(shell pwd) 19 | 20 | 21 | #/************************* Start your Makefile *******************************/ 22 | 23 | all: _cross 24 | @echo "###################################" 25 | @echo "# libflate" 26 | @echo "# Build up successfully" 27 | @echo "###################################" 28 | 29 | 30 | _cross: 31 | echo "Build libflate" 32 | 33 | $(MAKE) -C $(APP_SRC_DIR) 34 | 35 | install: 36 | $(STRIP) --strip-debug --remove-section=.note --remove-section=.comment $(APP_SRC_DIR)/libflate.so 37 | cp $(APP_SRC_DIR)/libflate.so $(FILESYSTEM_DIR)/lib/ 38 | 39 | clean: 40 | echo "Clean libflate" 41 | $(MAKE) -C $(APP_SRC_DIR) distclean 42 | 43 | #/************************* End your Makefile *******************************/ 44 | -------------------------------------------------------------------------------- /src/hello-CGIDebugLog.c: -------------------------------------------------------------------------------- 1 | /* hello-CGIDebugLog.c 2 | * 3 | * build: 4 | * gcc -I ../include \ 5 | hello-CGIDebugLog.c \ 6 | ../lib/libCGIDebugLogc.a \ 7 | -o hello-CGIDebugLog.cgi 8 | * 9 | * 10 | */ 11 | 12 | #include /* stdout, stderr, stdin */ 13 | #include 14 | #include 15 | 16 | #include "CGIDebugLogc.h" 17 | 18 | // #define __EMBEDDED_PLATFORM /* 仅在嵌入式平台在编译运行时注释掉这一行。 */ 19 | #ifndef __EMBEDDED_PLATFORM 20 | #include 21 | 22 | // int tcdbg_printf(char *message, int msg_len); 23 | 24 | void CGI_DEBUG_LOG(const char *fmt, ...){ 25 | va_list ap; 26 | va_start(ap, fmt); 27 | 28 | char dbg_message[128] = {'\0'}; 29 | /*ret =*/ vsprintf(dbg_message, fmt, ap); 30 | 31 | tcdbg_printf(dbg_message, strlen(dbg_message)); 32 | 33 | va_end(ap); 34 | } 35 | #else 36 | #define CGI_DEBUG_LOG( fmt, ...) /* other code... */ 37 | #endif 38 | 39 | 40 | int main(int argc, char const *argv[]) 41 | { 42 | 43 | CGIPrint( "HTTP head" ); 44 | // HTTP head 45 | //printf("\n") 46 | 47 | printf("\n"); 48 | 49 | CGIPrint( "HTTP Contents"); 50 | // HTTP contents 51 | printf("\n"); 52 | printf("\n"); 53 | printf("\n"); 54 | printf("\n"); 55 | printf("Hello\n"); 56 | printf("\n"); 57 | 58 | printf("\n"); 59 | printf("\t

Hello HTML

\n"); 60 | printf("\t

This is CGI program.

\n"); 61 | printf("\n"); 62 | printf("\n"); 63 | 64 | CGIPrint( "==== CGI END! ======"); 65 | 66 | return 0; 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/lib/Build_ename.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Create a new version of the file ename.c.inc by parsing symbolic 4 | # error names defined in errno.h 5 | # 6 | echo '#include ' | cpp -dM | 7 | sed -n -e '/#define *E/s/#define *//p' |sort -k2n | 8 | awk ' 9 | BEGIN { 10 | entries_per_line = 4 11 | line_len = 68; 12 | last = 0; 13 | varname =" enames"; 14 | print "static char *ename[] = {"; 15 | line = " /* 0 */ \"\""; 16 | } 17 | 18 | { 19 | if ($2 ~ /^E[A-Z0-9]*$/) { # These entries are sorted at top 20 | synonym[$1] = $2; 21 | } else { 22 | while (last + 1 < $2) { 23 | last++; 24 | line = line ", "; 25 | if (length(line ename) > line_len || last == 1) { 26 | print line; 27 | line = " /* " last " */ "; 28 | line = sprintf(" /* %3d */ ", last); 29 | } 30 | line = line "\"" "\"" ; 31 | } 32 | last = $2; 33 | ename = $1; 34 | for (k in synonym) 35 | if (synonym[k] == $1) ename = ename "/" k; 36 | 37 | line = line ", "; 38 | if (length(line ename) > line_len || last == 1) { 39 | print line; 40 | line = " /* " last " */ "; 41 | line = sprintf(" /* %3d */ ", last);; 42 | } 43 | line = line "\"" ename "\"" ; 44 | } 45 | } 46 | END { 47 | print line; 48 | print "};" 49 | print ""; 50 | print "#define MAX_ENAME " last; 51 | } 52 | ' 53 | 54 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/include/become_daemon.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 37-1 */ 12 | 13 | /* become_daemon.h 14 | 15 | Header file for become_daemon.c. 16 | */ 17 | #ifndef BECOME_DAEMON_H /* Prevent double inclusion */ 18 | #define BECOME_DAEMON_H 19 | 20 | /* Bit-mask values for 'flags' argument of becomeDaemon() */ 21 | 22 | #define BD_NO_CHDIR 01 /* Don't chdir("/") */ 23 | #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ 24 | #define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and 25 | stderr to /dev/null */ 26 | #define BD_NO_UMASK0 010 /* Don't do a umask(0) */ 27 | 28 | #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if 29 | sysconf(_SC_OPEN_MAX) is indeterminate */ 30 | 31 | // #define Ubuntu 32 | 33 | int becomeDaemon(int flags); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/include/become_daemon.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 37-1 */ 12 | 13 | /* become_daemon.h 14 | 15 | Header file for become_daemon.c. 16 | */ 17 | #ifndef BECOME_DAEMON_H /* Prevent double inclusion */ 18 | #define BECOME_DAEMON_H 19 | 20 | /* Bit-mask values for 'flags' argument of becomeDaemon() */ 21 | 22 | #define BD_NO_CHDIR 01 /* Don't chdir("/") */ 23 | #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ 24 | #define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and 25 | stderr to /dev/null */ 26 | #define BD_NO_UMASK0 010 /* Don't do a umask(0) */ 27 | 28 | #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if 29 | sysconf(_SC_OPEN_MAX) is indeterminate */ 30 | 31 | // #define Ubuntu 32 | 33 | int becomeDaemon(int flags); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | # lib/Makefile 2 | # 3 | # 4 | 5 | CC = gcc 6 | 7 | MAKE = make 8 | 9 | COPY = cp 10 | MOVE = mv 11 | 12 | Libraries := ../libraries 13 | 14 | Flate := flate 15 | CGIC := cgic 16 | 17 | .PHONY: all clean clean_cgic clean_all $(Libraries) $(Flate) $(CGIC) 18 | 19 | all: libCGIDebugLogc.a libcgic.a libflate.a 20 | 21 | # libCGIDebugLogc.a: $() 22 | libCGIDebugLogc.a: $(Libraries)/libCGIDebugLogc.a 23 | $(MOVE) $(Libraries)/$@ ./ 24 | @echo ">>>>> finish build libCGIDebugLogc.a <<<<<<" 25 | 26 | 27 | libcgic.a: $(CGIC) 28 | # -[o] 根据 “配置文件”(未实现)决定 cgic 的版本; 默认-cgic, 201-cgic201 29 | make --directory=$< 30 | cp $>>>> finish build libcgic.a <<<<<<" 32 | 33 | libflate.a: $(Flate) 34 | cp $>>>> finish build libcgic.a <<<<<<" 36 | 37 | $(Flate): 38 | make --directory=$@ 39 | 40 | $(Libraries)/libCGIDebugLogc.a: 41 | make --directory=$(Libraries) CGIDebugLog 42 | 43 | 44 | clean: 45 | rm -f libcgic.a 46 | $(MAKE) --directory=cgic clean ### -[o] directory depends on config file. 47 | 48 | rm -f libCGIDebugLogc.a 49 | $(MAKE) --directory=$(Libraries) clean 50 | 51 | rm -f libflate.a 52 | $(MAKE) --directory=$(Flate) clean 53 | 54 | rm -f *.so 55 | 56 | 57 | clean_cgic: 58 | rm -f libcgic.a 59 | $(MAKE) --directory=cgic clean ### -[o] directory depends on config file. 60 | 61 | 62 | clean_all: 63 | rm -f libcgic.a 64 | $(MAKE) --directory=cgic clean ### -[o] directory depends on config file. 65 | 66 | rm -f libCGIDebugLogc.a 67 | $(MAKE) --directory=$(Libraries) clean_all 68 | 69 | rm -f libflate.a 70 | $(MAKE) --directory=$(Flate) clean 71 | 72 | rm -f *.so 73 | 74 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/socketClient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # file name: socketClient.py 4 | # author : Huaxing Lin 5 | # E-mail : joseph.lin@aliyun.com 6 | # 7 | # ------- May/21/2018 22:37 ----- 8 | # v0.0.1 : 基本 function 9 | # change : 删除和 TTY device 有关的代码。 10 | # 11 | # ### SOCKET PROGRAMMING ### 12 | # function : 通过命令行指定 server port, 13 | # 请求通过 port 和server 建立 socket 连接 14 | # 发送通过命令行指定的 message 到 server。 15 | # message code: utf-8 16 | # 17 | 18 | ### 19 | ### import pakages 20 | ### 21 | import sys 22 | 23 | import socket 24 | 25 | ### 26 | ### global variables 27 | ## 28 | 29 | ## 30 | ## for Debug 31 | ## 32 | doThis = 2 33 | 34 | 35 | ### 36 | ### function: 37 | ### 38 | def foo(): 39 | print( "foo function.", file=sys.stdout) 40 | #fed function 41 | 42 | 43 | ### 44 | ### running logical: 45 | ### 46 | def main(): 47 | argc = len(sys.argv) 48 | if argc != 3: 49 | print ( "usage: $ %s " % sys.argv[0], file=sys.stderr ) 50 | sys.exit(1) 51 | #fi 52 | 53 | foo() 54 | 55 | ### socket client: 56 | ## reference: runoob.com/python3/python3-socket.html 57 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 58 | 59 | ## 获取本地主机名 60 | hostname = socket.gethostname() 61 | 62 | ## 设置服务器监听的端口去连接 63 | port = int(sys.argv[1]) ## 字符串转数字 C语言的 atoi() 64 | 65 | ## 连接服务器, 指定主机和端口 66 | s.connect((hostname, port)) 67 | 68 | sendMsg = "%s" %sys.argv[2] ## $ 0: 1: 2: 69 | s.send(sendMsg.encode('utf-8')) 70 | 71 | s.close() 72 | 73 | sys.exit(0) 74 | ##fed func main 75 | 76 | 77 | if __name__ == "__main__": 78 | main() 79 | ##END running program. -------------------------------------------------------------------------------- /src/py_getEnvir.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # 4 | # Note: 5 | # get localhost/cgi-bin/getEvir.py 没有输出, 使用浏览器的 F12 -> network 查看了一下package 6 | # 发现是因为输出不完整的原因。 只是输出到 7 | # 现象和 hello.py 类似, 本来以为是 sys.exit(0) 的原因,误以为它没有真正的好好顺序执行。 8 | # 在这里则觉得会不会是 print 分次太多,所以Apache2 没有等待执行结束就退出。 9 | # 最后发现, 原来是这里的中文原因。 输出的代码中带有中文, 则此调用CGI的进程就死掉了。 10 | # 11 | # 可能是因为运行的平台, raspberry Pi 安装的是标准版, 没有选择中文安装,所以对中文的支持可能有问题。 12 | # 具体原因还有待排查,这边写输出先不要用中文。 13 | # 14 | # 👆 中文输出 soluton: R394 15 | # Reference: http://www.runoob.com/python3/python3-cgi-programming.html#div-comment-26430 16 | # 17 | 18 | ### 19 | ### rely on packages 20 | ### 21 | import os 22 | import sys 23 | 24 | import io 25 | 26 | ### 27 | ### global variable 28 | ### 29 | # ... 30 | ## fix 因为中文输出导致进程死掉 31 | sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') 32 | 33 | ### 34 | ### funciton define 35 | ### 36 | def main(): 37 | ### response heard: 38 | # print ( 'Content-type: text/html') 39 | # print () 40 | str = 'Content-type: text/html' + '\r\n' 41 | str = str + '\r\n' + '\r\n' 42 | 43 | str = str + "" + '\r\n' 44 | str = str + "Envirnments avaible(环境变量):
" + '\r\n' 45 | str = str + "
    " + '\r\n' 46 | for key in os.environ.keys(): 47 | tmp = "
  • %30s : %s
  • " % (key, os.environ[key]) 48 | str = str + tmp + '\r\n' 49 | str = str + "
" + '\r\n' 50 | 51 | print (str) 52 | #END func main 53 | 54 | ### 55 | ### program running: 56 | ### 57 | if __name__ == "__main__": 58 | main() 59 | #END running main funciton. 60 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/libflate.mk: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # 3 | #libflate 4 | # 5 | ############################################################# 6 | 7 | LIBFLATE_CONFIGURE_DIR:=$(shell pwd)/package/libflate 8 | LIBFLATE_LIB_DIR:=$(STAGING_DIR)/usr/lib 9 | LIBFLATE_INC_DIR:=$(STAGING_DIR)/include 10 | LIB_DIR:=$(TARGET_DIR)/lib 11 | 12 | ############################################################# 13 | # 14 | # Build recipes 15 | # 16 | ############################################################# 17 | 18 | EXTRA_WARNINGS = -Wall -Wshadow -Werror 19 | 20 | # define _GNU_SOURCE to get prototypes for strcasecmp and strncasecmp 21 | # Programs are present in the C library; this #define just insures their prototype is defined. 22 | # EXTRA_DEFINES = -D_GNU_SOURCE 23 | STRIP = $(TARGET_CROSS)strip 24 | 25 | libflate: 26 | make -C $(LIBFLATE_CONFIGURE_DIR) TARGET="$(TARGET_DIR)" BUILD="$(BUILD_DIR)" \ 27 | CC=$(TARGET_CC) LD=$(TARGET_CROSS)ld STRIP=$(STRIP) $(EXTRA_WARNINGS) all; 28 | (cd $(LIBFLATE_CONFIGURE_DIR); \ 29 | cp -fa $(LIBFLATE_CONFIGURE_DIR)/libflate.so $(LIBFLATE_LIB_DIR); \ 30 | cp -fa $(LIBFLATE_CONFIGURE_DIR)/libflate.so $(LIB_DIR); \ 31 | cp -fa $(LIBFLATE_CONFIGURE_DIR)/flate.h $(LIBFLATE_INC_DIR); \ 32 | ); 33 | 34 | libflate-clean: 35 | -$(MAKE) -C $(LIBFLATE_CONFIGURE_DIR) clean 36 | rm -rf $(LIBFLATE_CONFIGURE_DIR)/*.o 37 | 38 | libflate-dirclean: 39 | 40 | 41 | ############################################################# 42 | # 43 | # Toplevel Makefile options 44 | # 45 | ############################################################# 46 | ifeq ($(strip $(BR2_PACKAGE_LIBFLATE)),y) 47 | TARGETS+=libflate 48 | endif 49 | 50 | -------------------------------------------------------------------------------- /WorkPath/lib/python3.5/daemon/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # daemon/__init__.py 4 | # Part of ‘python-daemon’, an implementation of PEP 3143. 5 | # 6 | # Copyright © 2009–2016 Ben Finney 7 | # Copyright © 2006 Robert Niederreiter 8 | # 9 | # This is free software: you may copy, modify, and/or distribute this work 10 | # under the terms of the Apache License, version 2.0 as published by the 11 | # Apache Software Foundation. 12 | # No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details. 13 | 14 | """ Library to implement a well-behaved Unix daemon process. 15 | 16 | This library implements the well-behaved daemon specification of 17 | :pep:`3143`, “Standard daemon process library”. 18 | 19 | A well-behaved Unix daemon process is tricky to get right, but the 20 | required steps are much the same for every daemon program. A 21 | `DaemonContext` instance holds the behaviour and configured 22 | process environment for the program; use the instance as a context 23 | manager to enter a daemon state. 24 | 25 | Simple example of usage:: 26 | 27 | import daemon 28 | 29 | from spam import do_main_program 30 | 31 | with daemon.DaemonContext(): 32 | do_main_program() 33 | 34 | Customisation of the steps to become a daemon is available by 35 | setting options on the `DaemonContext` instance; see the 36 | documentation for that class for each option. 37 | 38 | """ 39 | 40 | from __future__ import (absolute_import, unicode_literals) 41 | 42 | from .daemon import DaemonContext 43 | 44 | 45 | # Local variables: 46 | # coding: utf-8 47 | # mode: python 48 | # End: 49 | # vim: fileencoding=utf-8 filetype=python : 50 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/include/error_functions.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-2 */ 12 | 13 | /* error_functions.h 14 | 15 | Header file for error_functions.c. 16 | */ 17 | #ifndef ERROR_FUNCTIONS_H 18 | #define ERROR_FUNCTIONS_H 19 | 20 | /* Error diagnostic routines */ 21 | 22 | void errMsg(const char *format, ...); 23 | 24 | #ifdef __GNUC__ 25 | 26 | /* This macro stops 'gcc -Wall' complaining that "control reaches 27 | end of non-void function" if we use the following functions to 28 | terminate main() or some other non-void function. */ 29 | 30 | #define NORETURN __attribute__ ((__noreturn__)) 31 | #else 32 | #define NORETURN 33 | #endif 34 | 35 | void errExit(const char *format, ...) NORETURN ; 36 | 37 | void err_exit(const char *format, ...) NORETURN ; 38 | 39 | void errExitEN(int errnum, const char *format, ...) NORETURN ; 40 | 41 | void fatal(const char *format, ...) NORETURN ; 42 | 43 | void usageErr(const char *format, ...) NORETURN ; 44 | 45 | void cmdLineErr(const char *format, ...) NORETURN ; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/include/error_functions.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-2 */ 12 | 13 | /* error_functions.h 14 | 15 | Header file for error_functions.c. 16 | */ 17 | #ifndef ERROR_FUNCTIONS_H 18 | #define ERROR_FUNCTIONS_H 19 | 20 | /* Error diagnostic routines */ 21 | 22 | void errMsg(const char *format, ...); 23 | 24 | #ifdef __GNUC__ 25 | 26 | /* This macro stops 'gcc -Wall' complaining that "control reaches 27 | end of non-void function" if we use the following functions to 28 | terminate main() or some other non-void function. */ 29 | 30 | #define NORETURN __attribute__ ((__noreturn__)) 31 | #else 32 | #define NORETURN 33 | #endif 34 | 35 | void errExit(const char *format, ...) NORETURN ; 36 | 37 | void err_exit(const char *format, ...) NORETURN ; 38 | 39 | void errExitEN(int errnum, const char *format, ...) NORETURN ; 40 | 41 | void fatal(const char *format, ...) NORETURN ; 42 | 43 | void usageErr(const char *format, ...) NORETURN ; 44 | 45 | void cmdLineErr(const char *format, ...) NORETURN ; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogc/CGIDebugLogc.c: -------------------------------------------------------------------------------- 1 | /* CGIDebugLogc.c 2 | * Author : Joseph Lin 3 | * E-mail : joseph.lin@aliyun.com 4 | * 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include /* should notice the sys/ directory. */ 14 | 15 | #include 16 | 17 | #include "CGIDebugLogc.h" 18 | 19 | const char *serverIP = "127.0.0.1"; // localhost. 20 | const int serverPort = 21919; // the default DebugLog server port. 21 | 22 | const int RET_SUCCESS = 0; 23 | const int RET_FAILURE = -1; 24 | 25 | /* 26 | * msg_len: should not include '\0'; the actually length. 27 | */ 28 | int CGIdbg_printf(char *message, int msg_len){ 29 | int sock = socket(PF_INET, SOCK_STREAM, 0); 30 | if ( sock==-1 ) return RET_FAILURE; 31 | 32 | struct sockaddr_in serv_addr; 33 | memset(&serv_addr, 0, sizeof(serv_addr)); 34 | serv_addr.sin_family = AF_INET; 35 | serv_addr.sin_addr.s_addr = inet_addr(serverIP); // IP: server ip 36 | serv_addr.sin_port = htons( serverPort ); 37 | 38 | if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 39 | return RET_FAILURE; 40 | 41 | int send_len = write(sock, message, msg_len); 42 | 43 | close(sock); 44 | 45 | return RET_SUCCESS; 46 | } 47 | 48 | 49 | 50 | int tcdbg_printf(char *message, int msg_len){ 51 | return CGIdbg_printf(message, msg_len); 52 | } 53 | 54 | #define MAX_DEBUG_LOG_LENGTH 1024 55 | int CGIPrint(const char *fmt, ...){ 56 | va_list ap; 57 | va_start(ap, fmt); 58 | 59 | char dbg_message[MAX_DEBUG_LOG_LENGTH] = {'\0'}; 60 | int len = vsprintf( dbg_message, fmt, ap ); 61 | 62 | CGIdbg_printf(dbg_message, strlen(dbg_message) ); 63 | 64 | va_end(ap); 65 | 66 | return len; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Dev_WebServer/Makefile: -------------------------------------------------------------------------------- 1 | # mini_httpd_dev/Makefile 2 | # 3 | 4 | 5 | ## get mini_httpd-.tar.gz packages 6 | ## $ wget http://www.acme.com/software/mini_httpd/mini_httpd-1.19.tar.gz 7 | ## 8 | 9 | TAR = tar 10 | TARFLAGS_GZ = -xzvf 11 | TARFLAGS_BZ2 = -jxvf 12 | 13 | UNZIP = unzip 14 | 15 | MAKE = make 16 | 17 | CD = cd 18 | MOVE = mv 19 | COPY = cp 20 | RM = rm 21 | 22 | 23 | PACKAGE_DIR = packages 24 | 25 | WEB_SERVER = mini_httpd 26 | WEB_SERV_SRC_DIR = mini_httpd 27 | 28 | WEB_SERV_PACKAGE_NAME = mini_httpd-1.19.tar.gz 29 | WEB_SERV_PACKAGE_DIR = mini_httpd-1.19 30 | 31 | 32 | .PHONY: decompression run_patch init all clean install test runserver $(WEB_SERVER) 33 | 34 | all: $(WEB_SERVER) 35 | 36 | 37 | $(WEB_SERVER): 38 | $(MAKE) --directory=$(WEB_SERV_SRC_DIR) 39 | 40 | 41 | decompression: 42 | $(TAR) $(TARFLAGS_GZ) $(PACKAGE_DIR)/$(WEB_SERV_PACKAGE_NAME) \ 43 | -C $(shell pwd) 44 | $(MOVE) $(WEB_SERV_PACKAGE_DIR) $(WEB_SERV_SRC_DIR) 45 | 46 | run_patch: 47 | chmod +w $(shell pwd)/$(WEB_SERV_SRC_DIR)/htpasswd.c 48 | PROJ_DIR=$(shell pwd) MINI_HTTPD_SOURCE_DIR=$(WEB_SERV_SRC_DIR) python3 \ 49 | script/build_patch.py 50 | 51 | init: decompression run_patch 52 | mkdir run 53 | mkdir -p run/var/log 54 | mkdir -p run/var/www/html 55 | mkdir -p run/var/www/cgi-bin 56 | 57 | 58 | test: 59 | @echo "not implement yet" 60 | 61 | 62 | runserver: $(WEB_SERVER)/$(WEB_SERVER) 63 | PROJ_DIR=$(shell pwd) CONF_DIR=conf TEMPLATE_FILE=mini_httpd.conf.jinja2 python3 \ 64 | $(shell pwd)/script/mini_httpd_conf_patch.py 65 | 66 | $(WEB_SERV_SRC_DIR)/$(WEB_SERVER) -C $(shell pwd)/conf/mini_httpd.conf 67 | 68 | stopserver: 69 | kill -15 $(shell cat $(shell pwd)/run/mini_httpd.pid) 70 | $(RM) $(shell pwd)/run/mini_httpd.pid 71 | 72 | 73 | install: 74 | @echo "not implement yet" 75 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # Demo 2 | 3 | 快速验证 *.c => *.cgi 功能。 4 | 5 | 6 | 7 | [TOC] 8 | 9 | ## Apache2 配置 10 | 11 | 1. CGI mod enable 12 | 13 | ```shell 14 | $ cd /etc/apache2 15 | $ sudo vim mods-avaiable/cgi.load 16 | LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so 17 | + AddHandler cgi-script .cgi .pl .py .sh 18 | ~ 19 | ~ 20 | :wq 21 | $ 22 | $ sudo ln -s /etc/apache2/mods-available/cgid.conf /etc/apache2/mods-enabled/cgid.conf 23 | $ sudo ln -s /etc/apache2/mods-available/cgid.load /etc/apache2/mods-enabled/cgid.load 24 | $ sudo ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/cgi.load 25 | $ 26 | ``` 27 | 28 | 2. CGI path 29 | 30 | ```shell 31 | $ cd /etc/apache2 32 | $ sudo vim conf-available/serve-cgi-bin.conf 33 | [...] 34 | 35 | 36 | 37 | - ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 38 | + ScriptAlias /cgi-bin/ /var/www/cgi-bin/ 39 | - 40 | + 41 | AllowOverride None 42 | Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch 43 | Require all granted 44 | 45 | [...] 46 | :wq 47 | ``` 48 | 49 | 3. Create CGI Path 50 | 51 | ```shell 52 | $ sudo mkdir -p /var/www/cgi-bin/ 53 | ``` 54 | 55 | 56 | 57 | 4. restart 58 | 59 | ```shell 60 | $ /etc/init.d/apache2 restart 61 | ``` 62 | 63 | 64 | 65 | 66 | 67 | ------ 68 | 69 | 70 | 71 | ## Hello World 72 | 73 | ```shell 74 | $ cd helloworld 75 | $ tar -xzvf ///cgic207.tar.gz -C ./ # cgi201, cgi205, cgi207 is version 76 | .... 77 | $ make all 78 | $ ls -lF 79 | ... cgic207/ 80 | ... helloworld.c 81 | ... helloworld.cgi 82 | ... libcgic.a 83 | ... Makefile 84 | $ sudo make install 85 | ``` 86 | 87 | **访问验证:** 88 | 89 | `http:// or /cgi-bin/helloworld.cgi` 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /lib/cgic/support.txt: -------------------------------------------------------------------------------- 1 | Support for CGIC 2 | ---------------- 3 | 4 | ____ 5 | / \ 6 | | STOP | 7 | \____/ 8 | 9 | Are you getting a "server error," indicating that your web server 10 | "cannot allow POST to this URL," or a similar message? YOU MUST 11 | CONFIGURE YOUR WEB SERVER TO ALLOW CGI PROGRAMS, AND YOU MUST 12 | INSTALL CGI PROGRAMS IN THE LOCATION (OR WITH THE EXTENSION) THAT 13 | YOUR WEB SERVER EXPECTS TO SEE. Please don't send me email about 14 | this, unless you are purchasing commercial support. It is strictly 15 | between you and your web server's documentation, or between you and 16 | your ISP. If you wish to purchase commercial support, we will gladly 17 | attempt to help you resolve such problems, but the cooperation of 18 | your web server administrator will be necessary in most cases. Thanks! 19 | 20 | Free Support 21 | ------------ 22 | 23 | Anyone can mail questions about the gd and cgic libraries to 24 | boutell@boutell.com. However, I receive a very large volume of email on 25 | many subjects, and while I do my best to respond to all queries this can 26 | take some time. Sometimes the response must take the form of an eventual 27 | new release or an addition to a FAQ or other document, as opposed to an 28 | detailed individual response. 29 | 30 | Hourly Support 31 | -------------- 32 | 33 | Those requiring support in detail may arrange for direct support 34 | from the author, Thomas Boutell, at the rate of $50/hr, billed 35 | directly by credit card. Purchase orders are also accepted from 36 | Fortune 500 corporations and institutions in good standing. 37 | To make arrangements, contact support@boutell.com. Alternatively, 38 | use our free-form secure message page at: 39 | 40 | https://www.boutell.com/freeform/ 41 | 42 | To avoid delay and/or confusion, be sure to specifically mention that 43 | you wish to purchase CGIC support at the hourly rate above. 44 | 45 | -Thomas Boutell, boutell@boutell.com 46 | 47 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogd/CGIDebugLogd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | # file name: CGIDebugLogd.py 5 | # author : Joseph Lin 6 | # E-mail : joseph.lin@aliyun.com 7 | # 8 | # ------ May/21/2018 23:21 ------ 9 | # v1.0.1 10 | # change: 加入 socket。 11 | # 12 | # ------ 13 | # 14 | """ 15 | 16 | ### 17 | ### import pakages 18 | ### 19 | import sys 20 | 21 | from echo2tmnl import echo2 22 | 23 | import socket 24 | 25 | ### 26 | ### global variables 27 | ## 28 | HOST,PORT = '',21919 29 | 30 | 31 | ## 32 | ## for Debug 33 | ## 34 | doThis = 2 35 | 36 | 37 | ### 38 | ### function: 39 | ### 40 | def foo(): 41 | print( "foo function.", file=sys.stdout) 42 | #fed function 43 | 44 | def socketInit(): 45 | listen_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 46 | listen_socket.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) 47 | listen_socket.bind((HOST, PORT)) 48 | listen_socket.listen(1) 49 | 50 | ##print( "Serving DebugLog print on port %s..." % PORT ) 51 | return listen_socket 52 | #fed function socketInit. 53 | 54 | ## -[o] 待加入 捕获 Ctrl+C,中断处理函数。 55 | 56 | 57 | ### 58 | ### running logical: 59 | ### 60 | def main(argc, argv): 61 | # argc = len(sys.argv) 62 | #if argc != 3: 63 | if argc != 2: ## $ 64 | ## print( "usage: $ %s " %sys.argv[0], file=sys.stderr) 65 | sys.exit(1) 66 | 67 | listen_socket = socketInit() 68 | 69 | while True: 70 | (client_connection, client_address) = listen_socket.accept() 71 | msg = client_connection.recv(1024) ## -[o] 这句代码不是很完善 72 | 73 | msg = msg.decode("utf-8") 74 | #print("msg recive from client is:\n%s" %msg) ## -[x] 从显示效果来说,需要对发送过来的数据解码 75 | #echo2(sys.argv[1], sys.argv[2]) 76 | echo2(argv[1], msg) 77 | 78 | 79 | listen_socket.close() 80 | 81 | sys.exit(0) 82 | ##fed func main 83 | 84 | 85 | if __name__ == "__main__": 86 | main(len(sys.argv), sys.argv) 87 | ##END running program. 88 | -------------------------------------------------------------------------------- /demo/download/CGIDebugLogd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | # file name: CGIDebugLogd.py 5 | # author : Joseph Lin 6 | # E-mail : joseph.lin@aliyun.com 7 | # 8 | # ------ May/21/2018 23:21 ------ 9 | # v1.0.1 10 | # change: 加入 socket。 11 | # 12 | # ------ 13 | # 14 | """ 15 | 16 | ### 17 | ### import pakages 18 | ### 19 | import sys 20 | 21 | from echo2tmnl import echo2 22 | 23 | import socket 24 | 25 | ### 26 | ### global variables 27 | ## 28 | HOST, PORT = '', 21919 29 | 30 | 31 | ## 32 | # for Debug 33 | ## 34 | doThis = 2 35 | 36 | 37 | ### 38 | # function: 39 | ### 40 | def foo(): 41 | print("foo function.", file=sys.stdout) 42 | # fed function 43 | 44 | 45 | def socketInit(): 46 | listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 47 | listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 48 | listen_socket.bind((HOST, PORT)) 49 | listen_socket.listen(1) 50 | 51 | print("Serving DebugLog print on port %s..." % PORT) 52 | return listen_socket 53 | # fed function socketInit. 54 | 55 | # -[o] 待加入 捕获 Ctrl+C,中断处理函数。 56 | 57 | 58 | ### 59 | # running logical: 60 | ### 61 | def main(argc, argv): 62 | # argc = len(sys.argv) 63 | # if argc != 3: 64 | if argc != 2: # $ 65 | print("usage: $ {} " # " 66 | .format(sys.argv[0]), file=sys.stderr) 67 | sys.exit(1) 68 | 69 | listen_socket = socketInit() 70 | 71 | while True: 72 | (client_connection, client_address) = listen_socket.accept() 73 | msg = client_connection.recv(1024) # -[o] 这句代码不是很完善 74 | 75 | msg = msg.decode("utf-8") 76 | # print("msg recive from client is:\n%s" %msg) 77 | # ## -[x] 从显示效果来说,需要对发送过来的数据解码 78 | # echo2(sys.argv[1], sys.argv[2]) 79 | echo2(argv[1], msg) 80 | 81 | listen_socket.close() 82 | 83 | sys.exit(0) 84 | # fed func main 85 | 86 | 87 | if __name__ == "__main__": 88 | main(len(sys.argv), sys.argv) 89 | # END running program. 90 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/flate.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * * 3 | * Flate library (Fast Template) * 4 | * Copyright (C) 2001 Fabien Menemenlis (nihilist@dead-inside.org) * 5 | * * 6 | * This library is free software; you can redistribute it and/or * 7 | * modify it under the terms of the GNU Lesser General Public * 8 | * License as published by the Free Software Foundation; either * 9 | * version 2.1 of the License, or (at your option) any later version. * 10 | * * 11 | * This library is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 | * Lesser General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU Lesser General Public * 17 | * License along with this library; if not, write to the Free Software * 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 19 | * MA 02111-1307 USA * 20 | * * 21 | **************************************************************************/ 22 | 23 | #ifndef _LIB_FLATE_H_ 24 | #define _LIB_FLATE_H_ 25 | 26 | extern int templateSetFile(char *filename); 27 | extern void templateSetVar(char *fld, char *val); 28 | extern void templateDumpTableLine(char *line); 29 | extern void templatePrint(); 30 | extern char *templatePage(); 31 | extern void templateFreeMem(); 32 | #ifdef _USE_FETCH_ 33 | extern int templateSetFileURL(char *filename); 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /demo/download/download.c: -------------------------------------------------------------------------------- 1 | /***************************** 2 | * Build: 3 | * $ make all 4 | * 5 | * Install: 6 | * $ sudo make install 7 | * 8 | * Clean: 9 | * $ make clean 10 | * $ sudo rm -f /var/www/cgi-bin/*download_a_file.* 11 | * 12 | * Note: 13 | * you may need to run: 14 | * $ sudo ln -s /usr/include/x86_64-linux-gnu/sys/ /usr/include/sys 15 | * ### /\ example of Ubuntu 64bit /\ 16 | * 17 | ******************************/ 18 | 19 | #include "cgic.h" 20 | 21 | #include "utils.h" 22 | 23 | 24 | int handler_display(int *); 25 | 26 | 27 | int cgiMain(){ 28 | CGI_Println("cgiMain running..."); 29 | int ret = 0; 30 | int stat = STATUS_READY; 31 | 32 | typedef enum Act {ACT_INIT=0, DISPLAY, SUBMIT, Invalid} Act; 33 | Act act = ACT_INIT; 34 | int client_act = 0; 35 | 36 | cgiFormInteger("act", &client_act, (int)DISPLAY); 37 | act = (Act)client_act; 38 | 39 | switch(act){ 40 | case SUBMIT: 41 | stat = handler_submit(); 42 | return 0; 43 | case DISPLAY: 44 | handler_display(&stat); 45 | break; 46 | case Invalid: 47 | default: 48 | break; 49 | } 50 | return ret; 51 | } 52 | 53 | 54 | int handler_display(int *stat_p){ 55 | int ret = 0; 56 | 57 | if (*stat_p<0){ 58 | // pass 59 | } 60 | 61 | // cgiWriteEnvironment("/CHANGE/THIS/PATH/capcgi.dat"); 62 | cgiHeaderContentType("text/html"); 63 | 64 | char *html_file = "cgi_download.html"; 65 | 66 | FILE *fp = NULL; 67 | if ((fp = fopen(html_file, "r")) == NULL){ 68 | // LOG ERROR; 69 | return 1; 70 | } 71 | 72 | struct stat _fstat; 73 | if ( stat(html_file, &_fstat) == -1 ){ 74 | // log error; 75 | return 1; 76 | } 77 | 78 | char *html = NULL; 79 | long long read_size = 0; 80 | html = (char*)malloc(sizeof(char) * ((long long)_fstat.st_size + 1)); 81 | read_size = fread(html, sizeof(char), (long long)_fstat.st_size, fp); 82 | html[(long long)_fstat.st_size] = '\0'; 83 | if (read_size!=(long long)_fstat.st_size){ 84 | // log err; 85 | free(html); 86 | html = NULL; 87 | return 1; 88 | } 89 | 90 | fprintf(cgiOut, "%s", html); 91 | 92 | fflush(stdout); 93 | 94 | 95 | free(html); 96 | fclose(fp); 97 | return ret; 98 | } 99 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/lib/ename.c.inc: -------------------------------------------------------------------------------- 1 | static char *ename[] = { 2 | /* 0 */ "", 3 | /* 1 */ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO", "ENXIO", 4 | /* 7 */ "E2BIG", "ENOEXEC", "EBADF", "ECHILD", 5 | /* 11 */ "EAGAIN/EWOULDBLOCK", "ENOMEM", "EACCES", "EFAULT", 6 | /* 15 */ "ENOTBLK", "EBUSY", "EEXIST", "EXDEV", "ENODEV", 7 | /* 20 */ "ENOTDIR", "EISDIR", "EINVAL", "ENFILE", "EMFILE", 8 | /* 25 */ "ENOTTY", "ETXTBSY", "EFBIG", "ENOSPC", "ESPIPE", 9 | /* 30 */ "EROFS", "EMLINK", "EPIPE", "EDOM", "ERANGE", 10 | /* 35 */ "EDEADLK/EDEADLOCK", "ENAMETOOLONG", "ENOLCK", "ENOSYS", 11 | /* 39 */ "ENOTEMPTY", "ELOOP", "", "ENOMSG", "EIDRM", "ECHRNG", 12 | /* 45 */ "EL2NSYNC", "EL3HLT", "EL3RST", "ELNRNG", "EUNATCH", 13 | /* 50 */ "ENOCSI", "EL2HLT", "EBADE", "EBADR", "EXFULL", "ENOANO", 14 | /* 56 */ "EBADRQC", "EBADSLT", "", "EBFONT", "ENOSTR", "ENODATA", 15 | /* 62 */ "ETIME", "ENOSR", "ENONET", "ENOPKG", "EREMOTE", 16 | /* 67 */ "ENOLINK", "EADV", "ESRMNT", "ECOMM", "EPROTO", 17 | /* 72 */ "EMULTIHOP", "EDOTDOT", "EBADMSG", "EOVERFLOW", 18 | /* 76 */ "ENOTUNIQ", "EBADFD", "EREMCHG", "ELIBACC", "ELIBBAD", 19 | /* 81 */ "ELIBSCN", "ELIBMAX", "ELIBEXEC", "EILSEQ", "ERESTART", 20 | /* 86 */ "ESTRPIPE", "EUSERS", "ENOTSOCK", "EDESTADDRREQ", 21 | /* 90 */ "EMSGSIZE", "EPROTOTYPE", "ENOPROTOOPT", 22 | /* 93 */ "EPROTONOSUPPORT", "ESOCKTNOSUPPORT", 23 | /* 95 */ "EOPNOTSUPP/ENOTSUP", "EPFNOSUPPORT", "EAFNOSUPPORT", 24 | /* 98 */ "EADDRINUSE", "EADDRNOTAVAIL", "ENETDOWN", "ENETUNREACH", 25 | /* 102 */ "ENETRESET", "ECONNABORTED", "ECONNRESET", "ENOBUFS", 26 | /* 106 */ "EISCONN", "ENOTCONN", "ESHUTDOWN", "ETOOMANYREFS", 27 | /* 110 */ "ETIMEDOUT", "ECONNREFUSED", "EHOSTDOWN", "EHOSTUNREACH", 28 | /* 114 */ "EALREADY", "EINPROGRESS", "ESTALE", "EUCLEAN", 29 | /* 118 */ "ENOTNAM", "ENAVAIL", "EISNAM", "EREMOTEIO", "EDQUOT", 30 | /* 123 */ "ENOMEDIUM", "EMEDIUMTYPE", "ECANCELED", "ENOKEY", 31 | /* 127 */ "EKEYEXPIRED", "EKEYREVOKED", "EKEYREJECTED", 32 | /* 130 */ "EOWNERDEAD", "ENOTRECOVERABLE", "ERFKILL", "EHWPOISON" 33 | }; 34 | 35 | #define MAX_ENAME 133 36 | -------------------------------------------------------------------------------- /WorkPath/lib/python3.5/daemon/pidfile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # daemon/pidfile.py 4 | # Part of ‘python-daemon’, an implementation of PEP 3143. 5 | # 6 | # Copyright © 2008–2016 Ben Finney 7 | # 8 | # This is free software: you may copy, modify, and/or distribute this work 9 | # under the terms of the Apache License, version 2.0 as published by the 10 | # Apache Software Foundation. 11 | # No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details. 12 | 13 | """ Lockfile behaviour implemented via Unix PID files. 14 | """ 15 | 16 | from __future__ import (absolute_import, unicode_literals) 17 | 18 | from lockfile.pidlockfile import PIDLockFile 19 | 20 | 21 | class TimeoutPIDLockFile(PIDLockFile, object): 22 | """ Lockfile with default timeout, implemented as a Unix PID file. 23 | 24 | This uses the ``PIDLockFile`` implementation, with the 25 | following changes: 26 | 27 | * The `acquire_timeout` parameter to the initialiser will be 28 | used as the default `timeout` parameter for the `acquire` 29 | method. 30 | 31 | """ 32 | 33 | def __init__(self, path, acquire_timeout=None, *args, **kwargs): 34 | """ Set up the parameters of a TimeoutPIDLockFile. 35 | 36 | :param path: Filesystem path to the PID file. 37 | :param acquire_timeout: Value to use by default for the 38 | `acquire` call. 39 | :return: ``None``. 40 | 41 | """ 42 | self.acquire_timeout = acquire_timeout 43 | super(TimeoutPIDLockFile, self).__init__(path, *args, **kwargs) 44 | 45 | def acquire(self, timeout=None, *args, **kwargs): 46 | """ Acquire the lock. 47 | 48 | :param timeout: Specifies the timeout; see below for valid 49 | values. 50 | :return: ``None``. 51 | 52 | The `timeout` defaults to the value set during 53 | initialisation with the `acquire_timeout` parameter. It is 54 | passed to `PIDLockFile.acquire`; see that method for 55 | details. 56 | 57 | """ 58 | if timeout is None: 59 | timeout = self.acquire_timeout 60 | super(TimeoutPIDLockFile, self).acquire(timeout, *args, **kwargs) 61 | 62 | 63 | # Local variables: 64 | # coding: utf-8 65 | # mode: python 66 | # End: 67 | # vim: fileencoding=utf-8 filetype=python : 68 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Reference/r154-r201/CGIDebugLogd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | # 5 | # ------ 2018/May/07 23:07 ------ 6 | # v0.1.0 7 | # change: 加入 Socket, as server. 8 | # author: Huaxing Lin 9 | # e-mail: joseph.lin@liyun.com 10 | # Note : N/A 11 | # 12 | # ------ 13 | # 14 | """ 15 | 16 | ### 17 | ### import pakages 18 | ### 19 | import sys 20 | 21 | from echo2tmnl import echo2 22 | 23 | import socket 24 | 25 | ### 26 | ### global variables 27 | ## 28 | HOST,PORT = '',21919 29 | 30 | ## 31 | ## for Debug 32 | ## 33 | doThis = False 34 | 35 | 36 | ### 37 | ### function: 38 | ### 39 | def foo(): 40 | print( "foo function.", file=sys.stdout) 41 | #fed function 42 | 43 | def socketInit(): 44 | listen_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 45 | listen_socket.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) 46 | listen_socket.bind((HOST, PORT)) 47 | listen_socket.listen(1) 48 | 49 | print( "Serving DebugLog print on port %s..." % PORT ) 50 | return listen_socket 51 | #fed function socketInit. 52 | 53 | ## -[o] 待加入 捕获 Ctrl+C,中断处理函数。 54 | 55 | 56 | ### 57 | ### running logical: 58 | ### 59 | def main(): 60 | argc = len(sys.argv) 61 | 62 | if doThis: 63 | if argc != 3: 64 | print( "usage: $ %s " %sys.argv[0], file=sys.stderr) 65 | sys.exit(1) 66 | #fi 67 | 68 | echo2(sys.argv[1], sys.argv[2]) 69 | #fi doThis. 70 | 71 | foo() ## just for check program running. 72 | listen_socket = socketInit() 73 | 74 | while True: 75 | (client_connection, client_address) = listen_socket.accept() 76 | 77 | device_and_msg = client_connection.recv(1024) 78 | print( device_and_msg, file=sys.stdout ) 79 | print ( "type of socket msg: %s\n" %type(device_and_msg)) 80 | 81 | #device_and_msg = "%s" %device_and_msg 82 | device_and_msg = device_and_msg.decode("utf-8") 83 | print ( "type of socket msg: %s\n" %type(device_and_msg)) 84 | 85 | ### echo msg which recive from socket client to Terminal. 86 | (device, msg) = device_and_msg.split("\r\n", 1) 87 | print( "device: %s \nmsg: %s" %(device, msg), file=sys.stdout ) 88 | 89 | echo2(device, msg) 90 | 91 | #End while. 92 | 93 | listen_socket.close() 94 | 95 | sys.exit(0) 96 | ##fed func main 97 | 98 | 99 | if __name__ == "__main__": 100 | main() 101 | ##END running program. 102 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/src/CGIDebugLogd/DaemonEcho2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | # file name: DaemonEcho2 5 | # Author : Joseph Lin 6 | # E-mail : joseph.lin@aliyun.com 7 | # 8 | ### 9 | ### 10 | """ 11 | 12 | ### 13 | ### import packages 14 | ### 15 | import os, sys, io 16 | 17 | import time 18 | 19 | sys.path.append("lib/python3.5") 20 | try: 21 | from daemon import runner 22 | except ImportError as e: 23 | print( "ImportError: ", str(e), file=sys.stderr ) 24 | print( "run me as: WorkPath/ $ ./bin/DaemonEcho2 \n", 25 | "and check \"daemon/\" directory on /WorkPath/lib/python3.5\n ", 26 | file=sys.stderr) 27 | sys.exit(211) ## 211: env_err 28 | 29 | import CGIDebugLogd 30 | 31 | # import DaemonImportTest 32 | 33 | 34 | ### 35 | ### Global variables 36 | ### 37 | # doDebug = True 38 | doDebug = False 39 | 40 | 41 | 42 | 43 | ### 44 | ### functions define 45 | ### 46 | def foo(): 47 | pass 48 | 49 | class App(): 50 | __CGIDebugLogd_argc = 0 51 | __CGIDebugLogd_argv = list() 52 | 53 | def __init__(self, argc, argv, tty="/dev/null"): 54 | self.stdin_path = "/dev/null" 55 | self.stdout_path = tty 56 | self.stderr_path = tty 57 | self.pidfile_path = "/tmp/DaemonEcho2.pid" 58 | self.pidfile_timeout = 5 59 | 60 | self.__CGIDebugLogd_argc = argc 61 | self.__CGIDebugLogd_argv = argv 62 | 63 | def run(self): 64 | 65 | # while True: 66 | # print( "Hollo Python-daemon!") 67 | # time.sleep(5) 68 | if doDebug: 69 | print("__CGIDebugLogd_argc: ", str(self.__CGIDebugLogd_argc)) 70 | print("__CGIDebugLogd_argv: ", self.__CGIDebugLogd_argv) 71 | 72 | CGIDebugLogd.main(self.__CGIDebugLogd_argc, self.__CGIDebugLogd_argv) 73 | 74 | 75 | 76 | ### 77 | ### running logical 78 | ### 79 | def main(argc, argv): 80 | 81 | if argc!=2: 82 | print("Command error!\n", file=sys.stderr) 83 | sys.exit(210) ## CMD_ERR 84 | 85 | app = App(argc, argv, tty=argv[1]) 86 | daemon_runner = runner.DaemonRunner(app) 87 | daemon_runner.do_action() 88 | sys.exit(0) 89 | 90 | 91 | if __name__ == '__main__': 92 | CGIDebugLogd_argv = list() 93 | CGIDebugLogd_argc = len(sys.argv) - 1 94 | 95 | if CGIDebugLogd_argc!=2: 96 | print("Command error!\n", file=sys.stderr) 97 | sys.exit(210) ## CMD_ERR 98 | 99 | for i in range(len(sys.argv)): 100 | if i==1: 101 | continue 102 | CGIDebugLogd_argv.append(sys.argv[i]) 103 | 104 | if doDebug: 105 | print("CGIDebugLogd_argv: \n", 106 | CGIDebugLogd_argv) 107 | 108 | 109 | main(CGIDebugLogd_argc, CGIDebugLogd_argv) 110 | 111 | -------------------------------------------------------------------------------- /libraries/build_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | # file name: build_patch.py 5 | # 6 | # 7 | ### 8 | ### 9 | ### 10 | """ 11 | 12 | 13 | ### 14 | ### import packages 15 | ### 16 | import os, sys 17 | 18 | # import 19 | 20 | ### 21 | ### Global variables 22 | ### 23 | doDebug = True 24 | 25 | 26 | 27 | ### 28 | ### function define 29 | ### 30 | def foo(): 31 | pass 32 | #end foo() 33 | 34 | class CGIDebugLog(object): 35 | def __init__(self): 36 | pass 37 | 38 | def foo(self): 39 | pass 40 | #END class. 41 | 42 | 43 | class Mini_httpd(object): 44 | def __init__(self, sourceCodePath): 45 | self.htpasswd_filename = "htpasswd.c" 46 | self.mini_httpd_rootPath = sourceCodePath 47 | self.htpasswd_fullPath = self.mini_httpd_rootPath + '/' + self.htpasswd_filename 48 | 49 | def fix_htpasswd_build(self): 50 | index_head = -1 51 | index_tail = -1 52 | 53 | replace_funcName = "getline" 54 | tmp_data = None 55 | try: 56 | with open(self.htpasswd_fullPath) as htpasswd_fp: 57 | data = htpasswd_fp.read() 58 | 59 | """ 60 | 0...getline(...)...getline(...)... 61 | ^ ^ 62 | index_head index_tail 63 | """ 64 | index_head = data.find(replace_funcName) 65 | tmp_data = data[0:index_head] ## 0... 66 | tmp_data = tmp_data + "minihttpd_getline" ## 0...minihttpd_getline 67 | 68 | index_tail = data.find( replace_funcName, (index_head+len(replace_funcName)) ) 69 | ## 0...minihttpd_getline + (...)... 70 | tmp_data = tmp_data + data[(index_head+len(replace_funcName)):index_tail] 71 | tmp_data = tmp_data + "minihttpd_getline" ## (...)... + minihttpd_getline 72 | 73 | tmp_data = tmp_data + data[(index_tail+len(replace_funcName)):len(data)] 74 | except: 75 | print("fix_htpasswd_build() replace IO error.", file=sys.stderr) 76 | 77 | 78 | try: 79 | with open(self.htpasswd_fullPath, 'w') as rslt_fp: 80 | rslt_fp.write( "{}".format(tmp_data) ) 81 | except: 82 | print("fix_htpasswd_build() IO Write Error!", file=sys.stderr) 83 | 84 | #END class. 85 | 86 | 87 | ### 88 | ### running logical 89 | ### 90 | def main(): 91 | sourceCodePath = os.getcwd() ## /home/josephlin/.../github-EbdGUIDev 92 | if doDebug: 93 | print("work path: \"{}\"".format(sourceCodePath)) 94 | 95 | ## fix mini-httpd: 96 | mini_httpd_path = "mini_httpd-1.19" 97 | fix_mini_httpd_build = Mini_httpd(sourceCodePath + '/' + mini_httpd_path) 98 | fix_mini_httpd_build.fix_htpasswd_build() 99 | 100 | 101 | if __name__=="__main__": 102 | main() 103 | 104 | -------------------------------------------------------------------------------- /Dev_WebServer/script/build_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | # file name: build_patch.py 5 | # 6 | # 7 | ### 8 | ### 9 | ### 10 | """ 11 | 12 | import os 13 | import sys 14 | 15 | # import 16 | 17 | 18 | doDebug = True 19 | 20 | 21 | # sourceCodePath = os.getcwd() # /home/josephlin/.../github-EbdGUIDev 22 | # mini_httpd_path = "mini_httpd-1.19" 23 | PROJ_DIR = os.environ.get("PROJ_DIR", os.getcwd()) 24 | MINI_HTTPD_SOURCE_DIR = os.environ.get("MINI_HTTPD_SOURCE_DIR", 25 | "mini_httpd-1.19") 26 | 27 | 28 | class Mini_httpd(object): 29 | def __init__(self, sourceCodePath): 30 | self.htpasswd_filename = "htpasswd.c" 31 | self.mini_httpd_rootPath = sourceCodePath 32 | self.htpasswd_fullPath = self.mini_httpd_rootPath + '/' + self.htpasswd_filename 33 | 34 | def fix_htpasswd_build(self): 35 | index_head = -1 36 | index_tail = -1 37 | 38 | replace_funcName = "getline" 39 | tmp_data = None 40 | try: 41 | with open(self.htpasswd_fullPath) as htpasswd_fp: 42 | data = htpasswd_fp.read() 43 | 44 | """ 45 | 0...getline(...)...getline(...)... 46 | ^ ^ 47 | index_head index_tail 48 | """ 49 | index_head = data.find(replace_funcName) 50 | tmp_data = data[0:index_head] # 0... 51 | tmp_data = tmp_data + "minihttpd_getline" # 0...minihttpd_getline 52 | 53 | index_tail = data.find( 54 | replace_funcName, (index_head + len(replace_funcName))) 55 | # 0...minihttpd_getline + (...)... 56 | tmp_data = tmp_data + \ 57 | data[(index_head + len(replace_funcName)):index_tail] 58 | # (...)... + minihttpd_getline 59 | tmp_data = tmp_data + "minihttpd_getline" 60 | 61 | tmp_data = tmp_data + \ 62 | data[(index_tail + len(replace_funcName)):len(data)] 63 | except: 64 | import traceback; traceback.print_exc(); 65 | print("fix_htpasswd_build() replace IO error.", file=sys.stderr) 66 | 67 | try: 68 | with open(self.htpasswd_fullPath, 'w') as rslt_fp: 69 | rslt_fp.write("{}".format(tmp_data)) 70 | except: 71 | import traceback; traceback.print_exc(); 72 | print("fix_htpasswd_build() IO Write Error!", file=sys.stderr) 73 | 74 | 75 | def main(): 76 | source_code_path = PROJ_DIR + '/' + MINI_HTTPD_SOURCE_DIR 77 | if doDebug: 78 | print("mini_httpd source code path: '{}'".format(source_code_path)) 79 | 80 | if not os.path.exists(source_code_path): 81 | print("error mini_httpd source code path not exists!", file=sys.stderr) 82 | sys.exit(1) 83 | 84 | # fix mini-httpd: 85 | fix_mini_httpd_build = Mini_httpd(source_code_path) 86 | fix_mini_httpd_build.fix_htpasswd_build() 87 | 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | # 3 | # 4 | ### 5 | ### 6 | ### 7 | 8 | MAKE = make 9 | 10 | CD = cd 11 | MOVE = mv 12 | COPY = cp 13 | RM = rm 14 | 15 | # 16 | # / 17 | # |---- libraries/ 18 | # | |---- mini-httpd...tar.gz 19 | # | |---- DebugLog_solution.zip 20 | # | 21 | # | 22 | # |---- Makefile(<--this file) 23 | # | 24 | # |---- src/ 25 | # |---- html/ 26 | # |---- res/ 27 | # | 28 | # | 29 | # |---- WorkPath/ 30 | # 31 | 32 | 33 | ### 34 | ### 这里设定 libraries 的相关内容! 35 | ### 这里是文件夹 36 | ### 37 | Libraries := libraries 38 | 39 | Lib = lib 40 | CGI_PROGRAM = src 41 | 42 | Include = include 43 | 44 | .PHONY: $(Libraries) $(CGI_PROGRAM) LIB all install clean BIN clean_all \ 45 | $(Lib) $(Include) 46 | 47 | 48 | 49 | ### 50 | ### make all ==> 将所有 src/*.c --编译成--> src/*.cgi 51 | ### 需要 web.so cgic.so 等的支持, 依赖于 `$ make lib` 52 | ### 53 | #all: --mini_httpd-- --cgic.so-- --web.so-- 54 | 55 | ## make all = make lib + make src ##+ make Lib&Bin 56 | all: $(CGI_PROGRAM) 57 | 58 | init: $(Libraries)/mini_httpd-1.19.tar.gz 59 | cd $(Libraries) && tar -xzvf mini_httpd-1.19.tar.gz 60 | cd $(Libraries) && chmod +w mini_httpd-1.19/htpasswd.c 61 | cd $(Libraries) && python3 build_patch.py 62 | cd $(Lib) && $(COPY) -fr flate-2.0.1 flate 63 | 64 | ## DebugLog_solution.zip out of date. there is DebugLog_solution/ on trunk. 65 | # cd $(Libraries) && unzip DebugLog_solution.zip 66 | # ... else ... 67 | 68 | ### 69 | ### 应用程序 与 库链接 的依存关系 70 | ### (*.cgi) (mini_httpd, cgiDebugLogd, cgic.so web.so) 71 | ### 72 | $(CGI_PROGRAM): $(Libraries) LIB BIN Include 73 | 74 | ### 75 | ### 以下编译了 *.cgi, 并且确保依赖库要被编译。 76 | ### 77 | $(CGI_PROGRAM): 78 | $(MAKE) --directory=$@ 79 | ## 80 | ## ^^ 以上, 调用了 src/Makefile & libraries/Makefile 81 | ## 82 | 83 | SRC: include/flate.h include/cgic.h lib/libcgic.a lib/libflate.a lib/libCGIDebugLogc.a 84 | make --directory=src 85 | @echo "===== END build src/ ========" 86 | 87 | ### 88 | ### make lib => 需要 mini_httpd; cgic.a, flate.a, cgiDebugLog.a 89 | ### 90 | LIB: $(Libraries) 91 | $(MOVE) $(Libraries)/libCGIDebugLogc.a ./lib 92 | $(MAKE) --directory=lib all ## for libcigc.a 93 | 94 | $(Libraries): 95 | $(MAKE) --directory=$@ 96 | @echo "======= finished build libraries/ =======\n" 97 | 98 | BIN: 99 | $(MOVE) $(Libraries)/mini_httpd ./bin 100 | $(MOVE) $(Libraries)/CGIDebugLogd.py ./bin 101 | ### 102 | ### usage LINUX-C_daemon 103 | ### 104 | # $(COPY) $(Libraries)/daemonEcho2 ./bin 105 | ### 106 | ### usage python-dameon 107 | ### 108 | $(MOVE) $(Libraries)/DaemonEcho2 ./bin 109 | 110 | Include: 111 | $(MAKE) --directory=include 112 | 113 | ### 114 | ### make install ==> 将 src/*cgi html/*.html res/*.json *.js *.css 安装 115 | ### 需要检查当前是否有 CGIDebugLogd 在运行, 116 | ### 以及 mini_httpd 是否在运行。 117 | ### 没有的话, 需要打印提示消息! 118 | ### 119 | install: 120 | $(MAKE) --directory=$(Libraries) install 121 | 122 | 123 | 124 | clean: 125 | $(MAKE) --directory=$(Lib) clean 126 | $(MAKE) --directory=$(CGI_PROGRAM) clean 127 | rm -f lib/*.a 128 | rm -f bin/* 129 | 130 | 131 | 132 | clean_all: 133 | $(MAKE) --directory=$(Lib) clean_all 134 | $(MAKE) --directory=$(CGI_PROGRAM) clean 135 | rm -f bin/* 136 | 137 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/src/become_daemon.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 37-2 */ 12 | 13 | /* become_daemon.c 14 | 15 | A function encapsulating the steps in becoming a daemon. 16 | */ 17 | 18 | 19 | #include "become_daemon.h" 20 | #include "tlpi_hdr.h" 21 | 22 | // #ifndef Ubuntu 23 | // #define Ubuntu 24 | // #if defined(Ubuntu) 25 | // #include 26 | // #elif defined(RaspberryPi) 27 | // #include 28 | // #else 29 | // #include /* "apue" -> file status -> Chapter4 */ 30 | // #endif /* define Ubuntu | RaspberryPi */ 31 | // #endif /*no define Ubuntu */ 32 | //#include 33 | #include 34 | 35 | #include /* "apue" -> file control -> Section3.14 */ 36 | 37 | 38 | int /* Returns 0 on success, -1 on error */ 39 | becomeDaemon(int flags) 40 | { 41 | int maxfd, fd; 42 | 43 | switch (fork()) { /* Become background process */ 44 | case -1: return -1; 45 | case 0: break; /* Child falls through... */ 46 | default: _exit(EXIT_SUCCESS); /* while parent terminates */ 47 | } 48 | 49 | if (setsid() == -1) /* Become leader of new session */ 50 | return -1; 51 | 52 | #ifdef STRICT_DAEMON 53 | switch (fork()) { /* Ensure we are not session leader */ 54 | case -1: return -1; 55 | case 0: break; 56 | default: _exit(EXIT_SUCCESS); 57 | } 58 | #endif 59 | 60 | if (!(flags & BD_NO_UMASK0)) 61 | umask(0); /* Clear file mode creation mask */ 62 | 63 | if (!(flags & BD_NO_CHDIR)) 64 | chdir("/"); /* Change to root directory */ 65 | 66 | if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */ 67 | maxfd = sysconf(_SC_OPEN_MAX); 68 | if (maxfd == -1) /* Limit is indeterminate... */ 69 | maxfd = BD_MAX_CLOSE; /* so take a guess */ 70 | 71 | for (fd = 0; fd < maxfd; fd++) 72 | close(fd); 73 | } 74 | 75 | if (!(flags & BD_NO_REOPEN_STD_FDS)) { 76 | close(STDIN_FILENO); /* Reopen standard fd's to /dev/null */ 77 | 78 | fd = open("/dev/null", O_RDWR); 79 | 80 | if (fd != STDIN_FILENO) /* 'fd' should be 0 */ 81 | return -1; 82 | if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) 83 | return -1; 84 | if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) 85 | return -1; 86 | } 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /libraries/Makefile: -------------------------------------------------------------------------------- 1 | # libraries/Makefile 2 | # Author: Joseph Lin 3 | # E-mail: joseph.lin@aliyun.com 4 | # 5 | ### 6 | ### ------ 7 | ### v0.0.1 8 | ### change log: build CGIDebugLogd 相关 9 | ### 10 | ### ------ 11 | ### v0.0.2 12 | ### change log: build mini_httpd 相关 13 | ### 14 | ### ------ 15 | ### v0.0.3 16 | ### change log: build CGIDebugLogc 相关 17 | ### 18 | 19 | ## get mini_httpd-.tar.gz packages 20 | ## $ wget http://www.acme.com/software/mini_httpd/mini_httpd-1.19.tar.gz 21 | ## 22 | 23 | TAR = tar 24 | TARFLAGS_GZ = -xzvf 25 | TARFLAGS_BZ2 = -jxvf 26 | 27 | UNZIP = unzip 28 | 29 | MAKE = make 30 | 31 | CD = cd 32 | MOVE = mv 33 | COPY = cp 34 | RM = rm 35 | 36 | ### 37 | ### usage LINUX-C_daemon 38 | ### 39 | # EXE_CGIDebugLog := CGIDebugLogd.py daemonEcho2 libCGIDebugLogc.a 40 | 41 | ### 42 | ### usage python-dameon 43 | ### 44 | EXE_CGIDebugLog := CGIDebugLogd.py DaemonEcho2 libCGIDebugLogc.a 45 | 46 | 47 | EXE_MINIHTTPD := mini_httpd 48 | 49 | Lib_mini_httpd := mini_httpd-1.19 50 | Lib_CGIDebugLog := DebugLog_solution 51 | 52 | LibCGIDebugLogc := libCGIDebugLogc.a 53 | 54 | Lib_cgi := cgic 55 | Lib_template := flate 56 | ## cgic, flate, cgi-debug => **.a/so web.a 57 | 58 | #Libraries := $(Lib_mini_httpd) $(Lib_CGIDebugLog) $(Lib_cgi) $(Lib_template) 59 | 60 | .PHONY: all install clean $(Lib_CGIDebugLog) $(Lib_mini_httpd) 61 | 62 | ## cgic.so web.so 63 | all: $(EXE_MINIHTTPD) CGIDebugLog 64 | 65 | $(EXE_MINIHTTPD): $(Lib_mini_httpd) 66 | $(COPY) $(Lib_mini_httpd)/mini_httpd ./ 67 | @echo "$'\033[0;41m----- finish build mini_httpd! ---------\033[0m\n" 68 | 69 | CGIDebugLog: $(EXE_CGIDebugLog) 70 | @echo "$'\033[0;41m----- finish build CGIDebugLog! ---------\033[0m\n" 71 | $(EXE_CGIDebugLog): $(Lib_CGIDebugLog) 72 | 73 | CGIDebugLogd.py: 74 | $(MOVE) $(Lib_CGIDebugLog)/bin/$@ ./ 75 | ### 76 | ### usage LINUX-C_daemon 77 | ### 78 | # daemonEcho2: 79 | # $(COPY) $(Lib_CGIDebugLog)/bin/$@ ./ 80 | ### 81 | ### usage python-daemon 82 | ### 83 | DaemonEcho2: 84 | $(MOVE) $(Lib_CGIDebugLog)/bin/$@ ./ 85 | libCGIDebugLogc.a: 86 | $(MOVE) $(Lib_CGIDebugLog)/bin/$@ ./ 87 | 88 | 89 | ### 下面: 90 | ### 应用程序 与 库链接 的依存关系 91 | ### ------- 92 | ### 这里,应用程序并非如此,应用程序在 make lib 的时候没有马上编译, 93 | ### make lib 编译出库,并且copy 到一定的位置,提供 应用程序编译和运行环境。 94 | ### 95 | 96 | 97 | $(Lib_CGIDebugLog): 98 | $(MAKE) --directory=$(Lib_CGIDebugLog) 99 | @echo "\n" 100 | 101 | 102 | 103 | $(Lib_mini_httpd): 104 | $(MAKE) --directory=mini_httpd-1.19 105 | @echo "\n" 106 | 107 | 108 | 109 | 110 | install: 111 | ## for python lib 112 | $(MAKE) --directory=$(Lib_CGIDebugLog) install 113 | 114 | 115 | clean: 116 | ### 117 | ### usage LINUX-C_daemon 118 | ### 119 | # rm -f daemonEcho2 mini_httpd CGIDebugLogd.py libCGIDebugLogc.a 120 | ### 121 | ### usage python-daemon 122 | ### 123 | rm -f DaemonEcho2 mini_httpd CGIDebugLogd.py libCGIDebugLogc.a 124 | 125 | clean_all: 126 | ### 127 | ### usage LINUX-C_daemon 128 | ### 129 | # rm -f daemonEcho2 mini_httpd CGIDebugLogd.py libCGIDebugLogc.a 130 | ### 131 | ### usage python-daemon 132 | ### 133 | rm -f DaemonEcho2 mini_httpd CGIDebugLogd.py libCGIDebugLogc.a 134 | $(MAKE) --directory=mini_httpd-1.19 clean 135 | $(MAKE) --directory=DebugLog_solution clean 136 | @echo "$'\033[0;41m !!!!!! not remove mini_httpd-1.19 directory !!!!!!\033[0m\n" 137 | 138 | 139 | -------------------------------------------------------------------------------- /Dev_WebServer/script/mini_httpd_conf_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | # filename: mini_httpd.patch 5 | # Author : Joseph Lin 6 | # E-mail : joseph.lin@aliyun.com 7 | # 8 | # 9 | ### ----- 2018/Jul/22 12:30 10 | ### v0.0.1 11 | ### function: hard-code 路径,使用 jinja2 修改字符串 12 | ### 13 | ### ------ 2018/Jul/22 13:20 14 | ### v0.0.2 15 | ### change log: 默认打开的 mini_httpd.conf.jinja2 和 本脚本在同级目录, 16 | ### 获取 本脚本 所在的 绝对路径。 (merge r380 solution.) 17 | ### 18 | ### ------ 19 | ### 20 | """ 21 | 22 | import os 23 | import sys 24 | 25 | import jinja2 26 | from jinja2 import Environment, PackageLoader, select_autoescape 27 | from jinja2 import Template 28 | 29 | 30 | # 209 build-in function error 31 | # 210 command error 32 | # 219 IO Error 33 | # 1 common error 34 | # -1 func error 35 | # 911 bad error 36 | # 37 | 38 | doDebug = False 39 | 40 | PROJ_DIR = os.environ.get("PROJ_DIR", os.getcwd()) 41 | CONF_DIR = os.environ.get("CONF_DIR", "conf") 42 | TEMPLATE_FILE = os.environ.get("TEMPLATE_FILE", "mini_httpd.conf.jinja2") 43 | OUTPUT_FILE = os.environ.get("OUTPUT_FILE", "mini_httpd.conf") 44 | 45 | 46 | class BuildConfigurationFile(): 47 | def __init__(self, template_file, work_path, output_file): 48 | self.config_template_file = template_file 49 | self.work_path = work_path 50 | self.output_config_file = output_file 51 | 52 | def run(self): 53 | conf_data = "" 54 | try: 55 | with open(self.config_template_file, 'r') as conf_fp: 56 | conf_data = conf_fp.read() 57 | except IOError as e: 58 | print("\noperate mini_httpd.conf.jinja2 file fail!", 59 | file=sys.stderr) 60 | print("error with: %s " % str(e), file=sys.stderr) 61 | sys.exit(219) 62 | 63 | rootRelativePath = "var/www" 64 | cgiRelateRootPath = "cgi-bin" 65 | pidRelativePath = "" 66 | logRelativePath = "var/log" 67 | 68 | # replace variable of *.conf 69 | template = Template(conf_data) 70 | dstConfData = template.render( 71 | var_mini_httpd_root=self.work_path + "/" + rootRelativePath, 72 | var_mini_httpd_cgi_path=cgiRelateRootPath, 73 | var_mini_httpd_pid_path=self.work_path + "/" + pidRelativePath, 74 | var_mini_httpd_log_path=self.work_path + "/" + logRelativePath) 75 | 76 | if doDebug: 77 | print("dstConfData: \n%s" % dstConfData, file=sys.stderr) 78 | 79 | try: 80 | with open(self.output_config_file, 'w') as mini_httpd_fp: 81 | print("%s" % dstConfData, file=mini_httpd_fp) 82 | except IOError as e: 83 | print("\noperate mini_httpd.conf file fail!", file=sys.stderr) 84 | print("error with: %s " % str(e), file=sys.stderr) 85 | sys.exit(219) 86 | 87 | sys.exit(0) 88 | 89 | 90 | def main(): 91 | if doDebug: 92 | print("running main(): \n", file=sys.stderr) 93 | print("cwd: %s" % os.getcwd(), file=sys.stderr) 94 | 95 | template_file = '/'.join([PROJ_DIR, CONF_DIR, TEMPLATE_FILE]) 96 | work_path = '/'.join([PROJ_DIR, 'run']) 97 | output_file = '/'.join([PROJ_DIR, CONF_DIR, OUTPUT_FILE]) 98 | obj = BuildConfigurationFile(template_file, work_path, output_file) 99 | obj.run() 100 | 101 | 102 | if __name__ == '__main__': 103 | main() 104 | -------------------------------------------------------------------------------- /lib/flate-2.0.1/flate.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * * 3 | * Flate library (Fast Template) * 4 | * Copyright (C) 2013 Fabien Menemenlis (nihilist@dead-inside.org) * 5 | * * 6 | * This library is free software; you can redistribute it and/or * 7 | * modify it under the terms of the GNU Lesser General Public * 8 | * License as published by the Free Software Foundation; either * 9 | * version 2.1 of the License, or (at your option) any later version. * 10 | * * 11 | * This library is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 | * Lesser General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU Lesser General Public * 17 | * License along with this library; if not, write to the Free Software * 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 19 | * MA 02111-1307 USA * 20 | * * 21 | **************************************************************************/ 22 | 23 | #ifndef _LIB_FLATE_H_ 24 | #define _LIB_FLATE_H_ 25 | 26 | #include 27 | 28 | typedef struct tempUnit { 29 | struct tempUnit *next; 30 | struct tempUnit *prev; 31 | char *data; 32 | char *name; 33 | int tdata; 34 | int type; 35 | } tempUnit; 36 | 37 | typedef struct { 38 | char *name; 39 | tempUnit *unit; 40 | } st_ptr; 41 | 42 | typedef struct { 43 | tempUnit *UnitInit; 44 | st_ptr *tempVar, *tempZone, *tempTable; 45 | int tempnbVar, tempnbZone, tempnbTable; 46 | char *curzone, *curtable; 47 | char *tempBuf; 48 | char *cookies; 49 | int cookiessz; 50 | } Flate; 51 | 52 | typedef struct s_form { 53 | char *name; 54 | char *value; 55 | int sz; 56 | int (*checkfunc)(int c); 57 | struct s_form *next; 58 | } FlateForm; 59 | 60 | extern Flate *flateSetFile(Flate **tmplte, char *filename); 61 | extern void flateSetCookie(Flate *tmplte, char *name, char *value, char *domain, time_t expires); 62 | extern int flateGetCookie(char *value, int valuesz, char *cookie, int (*checkfunc)(int c)); 63 | extern void flateSetVar(Flate *tmplte, char *fld, char *val); 64 | extern void flateDumpTableLine(Flate *tmplte, char *line); 65 | extern void flatePrint(Flate *tmplte, char *type); 66 | extern char *flatePage(Flate *tmplte); 67 | extern void flateFreeMem(Flate *tmplte); 68 | extern FlateForm *flateAddForm(FlateForm *field, char *name, int sz, int (*checkfunc)(int c)); 69 | extern int flateReadForm(FlateForm *form); 70 | extern FlateForm *flateSetForm(char *s); 71 | extern char *flateGetForm(FlateForm *form, char *name); 72 | extern void flateDestroyForm(FlateForm **form); 73 | 74 | int templateSetFile( char filename[] ); 75 | int templateSetVar( char *fld, char *val ); 76 | int templatePrint(); 77 | int templateFreeMem(); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #include ../Makefile.inc 6 | 7 | #GEN_EXE = daemon_SIGHUP t_syslog test_become_daemon 8 | 9 | #EXE = ${GEN_EXE} ${LINUX_EXE} 10 | 11 | #all : ${EXE} 12 | 13 | #allgen : ${GEN_EXE} 14 | 15 | #clean : 16 | # ${RM} ${EXE} *.o 17 | 18 | #showall : 19 | # @ echo ${EXE} 20 | 21 | #${EXE} : ${LPLIB} # True as a rough approximation 22 | 23 | ### 24 | ### filename: Makefile 25 | ### author : Joseph Lin 26 | ### E-mail : joseph.lin@aliyun.com 27 | ### 28 | ### ------ May/24/2018 08:55 ------ 29 | ### v0.0.6 30 | ### author : Joseph Lin 31 | ### change : 将 .o 打包成 lib 库, 32 | ### Note : 使用 `-L -lbecome_daemon` 的方式来build,会出现函数链接错误 33 | ### 使用自动规则, 效果是: `libbecome_daemon.a` 全名在 gcc 命令中, 34 | ### 这样目前可以 build 成功。 35 | ### 36 | ### ------ May/24/2018 09:46 ------ 37 | ### v0.1.1 38 | ### author : Joseph Lin 39 | ### change : 删除编译 test_become_daemon 部分, 因为将该 src 文件夹上移出一层。 40 | ### 只编译 become_daemon 库! 41 | ### 42 | ### ------ 43 | ### 44 | 45 | 46 | 47 | 48 | CC=gcc 49 | RM=rm -f 50 | VPATH=include src lib test_src bin 51 | 52 | EXE=test 53 | 54 | MACRO_FLAGS = 55 | ## in CGI Debug Log solution use not strict daemon. 56 | #MACRO_FLAGS += -DSTRICT_DAEMON 57 | 58 | 59 | CPPFLAGS = -I include 60 | CPPFLAGS += $(MACRO_FLAGS) 61 | 62 | 63 | AR = ar 64 | ARFLAGS = rvu 65 | ### 66 | ### library of basic part: 67 | ### 68 | #libbecome_daemon.a: error_functions.o get_num.o become_daemon.o 69 | # $(AR) $(ARFLAGS) $@ $? 70 | 71 | lib/libbecome_daemon.a: libbecome_daemon.a(error_functions.o) libbecome_daemon.a(get_num.o) libbecome_daemon.a(become_daemon.o) 72 | 73 | lib/libbecome_daemon.a(error_functions.o): error_functions.o 74 | $(AR) $(ARFLAGS) $@ $? 75 | lib/libbecome_daemon.a(get_num.o): get_num.o 76 | $(AR) $(ARFLAGS) $@ $? 77 | lib/libbecome_daemon.a(become_daemon.o): become_daemon.o 78 | $(AR) $(ARFLAGS) $@ $? 79 | 80 | 81 | 82 | ### 83 | ### basic part: 84 | ### 85 | ./bin/error_functions.o: error_functions.c error_functions.h tlpi_hdr.h ename.c.inc 86 | ${CC} $(CPPFLAGS) -c $< -o $@ 87 | 88 | ./bin/get_num.o: get_num.c get_num.h tlpi_hdr.h error_functions.h 89 | ${CC} $(CPPFLAGS) -c $< -o $@ 90 | 91 | ./bin/become_daemon.o: become_daemon.c become_daemon.h tlpi_hdr.h error_functions.h get_num.h 92 | ${CC} $(CPPFLAGS) -c $< -o $@ 93 | 94 | 95 | 96 | 97 | 98 | 99 | .PHONY: clean del cleanall all help 100 | 101 | #all: $(EXE) 102 | # @echo "====== Finished build \"$(EXE)\" =========" 103 | all: libbecome_daemon.a 104 | @echo "====== Finished build \"$^\" =========\n" 105 | 106 | clean: 107 | ${RM} ./bin/*.o ./lib/*.a 108 | del: 109 | ${RM} ${EXE} 110 | 111 | cleanall: 112 | ${RM} ${EXE} ./bin/*.o ./lib/*.a daemonEcho2 113 | 114 | install: 115 | @echo "ERROR: this INSTALL not achieve for now!!!!" 116 | 117 | 118 | LIB: libbecome_daemon.a 119 | @echo "\n====== build \"$^\" finished!!! ========\n" 120 | 121 | 122 | ## help - The default goal 123 | MAKE = make 124 | AWK = awk 125 | SORT = sort 126 | PR = pr 127 | help: 128 | @ $(MAKE) --print-data-base --question | \ 129 | $(AWK) '/^[^.%][-A-Za-z0-9_]*:/ \ 130 | { print substr($$1, 1, length($$1)-1) }' | \ 131 | $(SORT) | \ 132 | $(PR) --omit-pagination --width=80 --columns=4 133 | 134 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/include/tlpi_hdr.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-1 */ 12 | 13 | /* tlpi_hdr.h 14 | 15 | Standard header file used by nearly all of our example programs. 16 | */ 17 | #ifndef TLPI_HDR_H 18 | #define TLPI_HDR_H /* Prevent accidental double inclusion */ 19 | 20 | // #ifndef Ubuntu 21 | // #define Ubuntu 22 | // #if defined(Ubuntu) 23 | // #include 24 | // #elif defined(RaspberryPi) 25 | // #include 26 | // #else 27 | // #include /* Type definitions used by many programs */ 28 | // /* "apue" -> file control -> Section 3.14 */ 29 | // #endif 30 | // #endif /* no define Ubuntu */ 31 | //#include 32 | #include 33 | 34 | #include /* Standard I/O functions */ 35 | #include /* Prototypes of commonly used library functions, 36 | plus EXIT_SUCCESS and EXIT_FAILURE constants */ 37 | #include /* Prototypes for many system calls */ 38 | #include /* Declares errno and defines error constants */ 39 | #include /* Commonly used string-handling functions */ 40 | 41 | #include "get_num.h" /* Declares our functions for handling numeric 42 | arguments (getInt(), getLong()) */ 43 | 44 | #include "error_functions.h" /* Declares our error-handling functions */ 45 | 46 | /* Unfortunately some UNIX implementations define FALSE and TRUE - 47 | here we'll undefine them */ 48 | 49 | #ifdef TRUE 50 | #undef TRUE 51 | #endif 52 | 53 | #ifdef FALSE 54 | #undef FALSE 55 | #endif 56 | 57 | typedef enum { FALSE, TRUE } Boolean; 58 | 59 | #define min(m,n) ((m) < (n) ? (m) : (n)) 60 | #define max(m,n) ((m) > (n) ? (m) : (n)) 61 | 62 | //------------ not use here daemon -------------------- 63 | // /* Some systems don't define 'socklen_t' */ 64 | // #if defined(__sgi) 65 | // typedef int socklen_t; 66 | // #endif 67 | 68 | // #if defined(__sun) 69 | // #include /* Has definition of FASYNC */ 70 | // #endif 71 | 72 | // #if ! defined(O_ASYNC) && defined(FASYNC) 73 | // /* Some systems define FASYNC instead of O_ASYNC */ 74 | // #define O_ASYNC FASYNC 75 | // #endif 76 | 77 | // #if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) 78 | // /* BSD derivatives usually have MAP_ANON, not MAP_ANONYMOUS */ 79 | // #define MAP_ANONYMOUS MAP_ANON 80 | //#endif 81 | 82 | // #if ! defined(O_SYNC) && defined(O_FSYNC) 83 | // /* Some implementations have O_FSYNC instead of O_SYNC */ 84 | // #define O_SYNC O_FSYNC 85 | // #endif 86 | 87 | // #if defined(__FreeBSD__) 88 | // /* FreeBSD uses these alternate names for fields in the sigval structure */ 89 | // #define sival_int sigval_int 90 | // #define sival_ptr sigval_ptr 91 | // #endif 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/include/tlpi_hdr.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-1 */ 12 | 13 | /* tlpi_hdr.h 14 | 15 | Standard header file used by nearly all of our example programs. 16 | */ 17 | #ifndef TLPI_HDR_H 18 | #define TLPI_HDR_H /* Prevent accidental double inclusion */ 19 | 20 | // #ifndef Ubuntu 21 | // #define Ubuntu 22 | // #if defined(Ubuntu) 23 | // #include 24 | // #elif defined(RaspberryPi) 25 | // #include 26 | // #else 27 | // #include /* Type definitions used by many programs */ 28 | // /* "apue" -> file control -> Section 3.14 */ 29 | // #endif 30 | // #endif /* no define Ubuntu */ 31 | //#include 32 | #include 33 | 34 | #include /* Standard I/O functions */ 35 | #include /* Prototypes of commonly used library functions, 36 | plus EXIT_SUCCESS and EXIT_FAILURE constants */ 37 | #include /* Prototypes for many system calls */ 38 | #include /* Declares errno and defines error constants */ 39 | #include /* Commonly used string-handling functions */ 40 | 41 | #include "get_num.h" /* Declares our functions for handling numeric 42 | arguments (getInt(), getLong()) */ 43 | 44 | #include "error_functions.h" /* Declares our error-handling functions */ 45 | 46 | /* Unfortunately some UNIX implementations define FALSE and TRUE - 47 | here we'll undefine them */ 48 | 49 | #ifdef TRUE 50 | #undef TRUE 51 | #endif 52 | 53 | #ifdef FALSE 54 | #undef FALSE 55 | #endif 56 | 57 | typedef enum { FALSE, TRUE } Boolean; 58 | 59 | #define min(m,n) ((m) < (n) ? (m) : (n)) 60 | #define max(m,n) ((m) > (n) ? (m) : (n)) 61 | 62 | //------------ not use here daemon -------------------- 63 | // /* Some systems don't define 'socklen_t' */ 64 | // #if defined(__sgi) 65 | // typedef int socklen_t; 66 | // #endif 67 | 68 | // #if defined(__sun) 69 | // #include /* Has definition of FASYNC */ 70 | // #endif 71 | 72 | // #if ! defined(O_ASYNC) && defined(FASYNC) 73 | // /* Some systems define FASYNC instead of O_ASYNC */ 74 | // #define O_ASYNC FASYNC 75 | // #endif 76 | 77 | // #if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) 78 | // /* BSD derivatives usually have MAP_ANON, not MAP_ANONYMOUS */ 79 | // #define MAP_ANONYMOUS MAP_ANON 80 | //#endif 81 | 82 | // #if ! defined(O_SYNC) && defined(O_FSYNC) 83 | // /* Some implementations have O_FSYNC instead of O_SYNC */ 84 | // #define O_SYNC O_FSYNC 85 | // #endif 86 | 87 | // #if defined(__FreeBSD__) 88 | // /* FreeBSD uses these alternate names for fields in the sigval structure */ 89 | // #define sival_int sigval_int 90 | // #define sival_ptr sigval_ptr 91 | // #endif 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /WorkPath/etc/mini_httpd/mini_httpd.patch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | # filename: mini_httpd.patch 5 | # Author : Joseph Lin 6 | # E-mail : joseph.lin@aliyun.com 7 | # 8 | # 9 | ### ----- 2018/Jul/22 12:30 10 | ### v0.0.1 11 | ### function: hard-code 路径,使用 jinja2 修改字符串 12 | ### 13 | ### ------ 2018/Jul/22 13:20 14 | ### v0.0.2 15 | ### change log: 默认打开的 mini_httpd.conf.jinja2 和 本脚本在同级目录, 16 | ### 获取 本脚本 所在的 绝对路径。 (merge r380 solution.) 17 | ### 18 | ### ------ 19 | ### 20 | """ 21 | 22 | 23 | ### 24 | ### import packages 25 | ### 26 | import os, sys 27 | 28 | import jinja2 29 | from jinja2 import Environment, PackageLoader, select_autoescape 30 | from jinja2 import Template 31 | 32 | 33 | ### 34 | ### Globale variables 35 | ### 36 | doDebug = False 37 | 38 | 39 | # 209 build-in function error 40 | # 210 command error 41 | # 219 IO Error 42 | # 1 common error 43 | # -1 func error 44 | # 911 bad error 45 | # 46 | 47 | ### 48 | ### function define 49 | ### 50 | def getCMDPath( argv0 ): 51 | sindex = 0 52 | if argv0[0] == '.' and argv0[1] == '/': 53 | sindex = 2 54 | else: 55 | pass 56 | 57 | pareseCMDRet = "" 58 | tmpStr = "" 59 | programName = "" 60 | point = 0 61 | while True: 62 | point = len(pareseCMDRet) + 1 63 | try: 64 | (tmpStr, programName) = argv0[(sindex + point-1):].split('/', 1) 65 | except: 66 | tmpStr = "" 67 | programName = argv0[(sindex + point-1):] 68 | 69 | if tmpStr != "": 70 | pareseCMDRet = pareseCMDRet + '/' 71 | programName = "" 72 | else: 73 | break 74 | pareseCMDRet = pareseCMDRet + tmpStr 75 | return (pareseCMDRet, programName) 76 | 77 | 78 | configJinja2Name = "mini_httpd.conf.jinja2" 79 | configName = "mini_httpd.conf" 80 | def main(): 81 | if doDebug: 82 | print ("running main(): \n", file=sys.stderr) 83 | print ("cwd: %s" %os.getcwd(), file=sys.stderr ) 84 | 85 | programName = "" 86 | CMDPath = "" 87 | (CMDPath, programName) = getCMDPath(sys.argv[0]) 88 | if doDebug: 89 | print("\n\nCMD path: {}\nprogram Name: {}\n".format(CMDPath, programName), file=sys.stderr) 90 | 91 | configJinja2Path = os.getcwd()+CMDPath 92 | 93 | ### get WorkPath path 94 | workPath = configJinja2Path 95 | # workPath = "anytesersdf2308as/s/adjfh/dsjlf" ## test "else" 96 | workPathIndex=workPath.find("WorkPath") 97 | if workPathIndex!=-1: 98 | workPath = workPath[0:workPathIndex+len("WorkPath")] 99 | else: 100 | print("!!!! get WorkPath fail!!!!!\n", file=sys.stderr) 101 | sys.exit(911) 102 | 103 | conf_fp = None 104 | conf_data = "" 105 | try: 106 | with open(configJinja2Path+"/"+configJinja2Name, 'r') as conf_fp: 107 | conf_data = conf_fp.read() 108 | except IOError as e: 109 | print ( "\noperate mini_httpd.conf.jinja2 file fail!", file=sys.stderr ) 110 | print ( "error with: %s " %str(e), file=sys.stderr) 111 | sys.exit(219) 112 | 113 | 114 | rootRelativePath = "var/www" 115 | cgiRelateRootPath = "cgi-bin" 116 | pidRelativePath = "var" 117 | logRelativePath = "var/log" 118 | 119 | ### replace variable of *.conf 120 | template = Template( conf_data ) 121 | dstConfData = template.render( 122 | var_mini_httpd_root= workPath+"/"+rootRelativePath, 123 | var_mini_httpd_cgi_path = cgiRelateRootPath, 124 | var_mini_httpd_pid_path = workPath+"/"+pidRelativePath, 125 | var_mini_httpd_log_path = workPath+"/"+logRelativePath ) 126 | 127 | if doDebug: 128 | print ( "dstConfData: \n%s" %dstConfData, file=sys.stderr ) 129 | 130 | try: 131 | with open(configJinja2Path+"/"+configName, 'w') as mini_httpd_fp: 132 | print ( "%s" %dstConfData, file=mini_httpd_fp ) 133 | except IOError as e: 134 | print ( "\noperate mini_httpd.conf file fail!", file=sys.stderr ) 135 | print ( "error with: %s " %str(e), file=sys.stderr) 136 | sys.exit(219) 137 | 138 | sys.exit(0) 139 | #end main. 140 | 141 | if __name__ == '__main__': 142 | main() 143 | #fi. 144 | 145 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/src/get_num.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-6 */ 12 | 13 | /* get_num.c 14 | 15 | Functions to process numeric command-line arguments. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "get_num.h" 23 | 24 | /* Print a diagnostic message that contains a function name ('fname'), 25 | the value of a command-line argument ('arg'), the name of that 26 | command-line argument ('name'), and a diagnostic error message ('msg'). */ 27 | 28 | static void 29 | gnFail(const char *fname, const char *msg, const char *arg, const char *name) 30 | { 31 | fprintf(stderr, "%s error", fname); 32 | if (name != NULL) 33 | fprintf(stderr, " (in %s)", name); 34 | fprintf(stderr, ": %s\n", msg); 35 | if (arg != NULL && *arg != '\0') 36 | fprintf(stderr, " offending text: %s\n", arg); 37 | 38 | exit(EXIT_FAILURE); 39 | } 40 | 41 | /* Convert a numeric command-line argument ('arg') into a long integer, 42 | returned as the function result. 'flags' is a bit mask of flags controlling 43 | how the conversion is done and what diagnostic checks are performed on the 44 | numeric result; see get_num.h for details. 45 | 46 | 'fname' is the name of our caller, and 'name' is the name associated with 47 | the command-line argument 'arg'. 'fname' and 'name' are used to print a 48 | diagnostic message in case an error is detected when processing 'arg'. */ 49 | 50 | static long 51 | getNum(const char *fname, const char *arg, int flags, const char *name) 52 | { 53 | long res; 54 | char *endptr; 55 | int base; 56 | 57 | if (arg == NULL || *arg == '\0') 58 | gnFail(fname, "null or empty string", arg, name); 59 | 60 | base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8 : 61 | (flags & GN_BASE_16) ? 16 : 10; 62 | 63 | errno = 0; 64 | res = strtol(arg, &endptr, base); 65 | if (errno != 0) 66 | gnFail(fname, "strtol() failed", arg, name); 67 | 68 | if (*endptr != '\0') 69 | gnFail(fname, "nonnumeric characters", arg, name); 70 | 71 | if ((flags & GN_NONNEG) && res < 0) 72 | gnFail(fname, "negative value not allowed", arg, name); 73 | 74 | if ((flags & GN_GT_0) && res <= 0) 75 | gnFail(fname, "value must be > 0", arg, name); 76 | 77 | return res; 78 | } 79 | 80 | /* Convert a numeric command-line argument string to a long integer. See the 81 | comments for getNum() for a description of the arguments to this function. */ 82 | 83 | long 84 | getLong(const char *arg, int flags, const char *name) 85 | { 86 | return getNum("getLong", arg, flags, name); 87 | } 88 | 89 | /* Convert a numeric command-line argument string to an integer. See the 90 | comments for getNum() for a description of the arguments to this function. */ 91 | 92 | int 93 | getInt(const char *arg, int flags, const char *name) 94 | { 95 | long res; 96 | 97 | res = getNum("getInt", arg, flags, name); 98 | 99 | if (res > INT_MAX || res < INT_MIN) 100 | gnFail("getInt", "integer out of range", arg, name); 101 | 102 | return (int) res; 103 | } 104 | -------------------------------------------------------------------------------- /lib/cgic/license.txt: -------------------------------------------------------------------------------- 1 | CGIC License Terms 2 | ------------------ 3 | 4 | Basic License 5 | ------------- 6 | 7 | CGIC, copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 by Thomas Boutell 8 | and Boutell.Com, Inc.. Permission is granted to use CGIC in any 9 | application, commercial or noncommercial, at no cost. HOWEVER, 10 | this copyright paragraph must appear on a "credits" page accessible 11 | in the public online and offline documentation of the program. 12 | Modified versions of the CGIC library should not be distributed without 13 | the attachment of a clear statement regarding the author of the 14 | modifications, and this notice may in no case be removed. 15 | Modifications may also be submitted to the author for inclusion 16 | in the main CGIC distribution. 17 | 18 | IF YOU WOULD PREFER NOT TO ATTACH THE ABOVE NOTICE to 19 | the public documentation of your application, consult the 20 | information which follows regarding the availability 21 | of a nonexclusive commercial license for CGIC. 22 | 23 | Commercial License 24 | ------------------ 25 | 26 | The price of a nonexclusive commercial license is $200 U.S. 27 | To purchase the license: 28 | 29 | 1. Print and sign two copies of the document below. 30 | 31 | 2. Send both copies, along with Visa, Mastercard, Discover, or 32 | Amex card number, cardholder's name, and expiration date 33 | OR a check for $200 in U.S. funds drawn on a U.S. bank, to: 34 | 35 | Boutell.Com, Inc. 36 | PO Box 63767 37 | Philadelphia, PA 19147 USA 38 | 39 | BE SURE TO INCLUDE AN EMAIL ADDRESS, as well as 40 | a postal address and phone number. 41 | 42 | 3. We will return one signed copy to you promptly. 43 | 44 | You will also receive swift notification of new 45 | versions of CGIC, in addition to ongoing 46 | email support. 47 | 48 | * * * 49 | 50 | CGIC Nonexclusive Commercial License 51 | 52 | The licensee named below is granted the right 53 | to utilize CGIC, major version 1 or 2, any minor 54 | version thereof, in CGI applications without the 55 | need for a credit notice of any kind. CGI applications 56 | developed by the holder of this license may be 57 | distributed freely in source code or binary form 58 | without additional fees or royalties. This license does 59 | not grant the right to use CGIC to create a development tool 60 | which passes on substantially all of the capabilities of the 61 | CGIC library to the user of the tool, unless that tool is 62 | to be used internally by the license holder only in order 63 | to develop CGI applications. This license may not 64 | be resold, but applications developed in accordance 65 | with the terms of the license may be distributed 66 | freely subject to the limitations described above. 67 | 68 | Future minor (2.x) versions of CGIC will be covered by this 69 | license free of charge. If significant defects of workmanship 70 | are discovered in version 2.x, minor releases to correct them 71 | will be made available before or at the same time that 72 | those defects are addressed in any future major version. 73 | Future "major" (3.x) versions will be available to 74 | licensees at an upgrade price of $50. 75 | 76 | If, for any reason, any portion of this license is found 77 | to be invalid, that portion of the license only 78 | is invalidated and the remainder of the agreement 79 | remains in effect. 80 | 81 | If this license has not been signed by Thomas Boutell 82 | or M. L. Grant on behalf of Boutell. Com, Inc., 83 | it is invalid. 84 | 85 | Licensee: _____________________ 86 | 87 | Complete Mailing Address: _____________________ 88 | 89 | _____________________ 90 | 91 | _____________________ 92 | 93 | Phone Number: _____________________ 94 | 95 | Email Address: _____________________ 96 | 97 | Signed for Boutell.Com, Inc.: _____________________ 98 | 99 | Date: _____________________ 100 | 101 | 102 | -------------------------------------------------------------------------------- /WorkPath/lib/python3.5/daemon/_metadata.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # daemon/_metadata.py 4 | # Part of ‘python-daemon’, an implementation of PEP 3143. 5 | # 6 | # Copyright © 2008–2016 Ben Finney 7 | # 8 | # This is free software: you may copy, modify, and/or distribute this work 9 | # under the terms of the Apache License, version 2.0 as published by the 10 | # Apache Software Foundation. 11 | # No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details. 12 | 13 | """ Package metadata for the ‘python-daemon’ distribution. """ 14 | 15 | from __future__ import (absolute_import, unicode_literals) 16 | 17 | import json 18 | import datetime 19 | 20 | import pkg_resources 21 | 22 | __metaclass__ = type 23 | 24 | 25 | distribution_name = "python-daemon" 26 | version_info_filename = "version_info.json" 27 | 28 | 29 | def get_distribution_version_info(filename=version_info_filename): 30 | """ Get the version info from the installed distribution. 31 | 32 | :param filename: Base filename of the version info resource. 33 | :return: The version info as a mapping of fields. If the 34 | distribution is not available, the mapping is empty. 35 | 36 | The version info is stored as a metadata file in the 37 | distribution. 38 | 39 | """ 40 | version_info = { 41 | 'release_date': "UNKNOWN", 42 | 'version': "UNKNOWN", 43 | 'maintainer': "UNKNOWN", 44 | } 45 | 46 | try: 47 | distribution = pkg_resources.get_distribution(distribution_name) 48 | except pkg_resources.DistributionNotFound: 49 | distribution = None 50 | 51 | if distribution is not None: 52 | if distribution.has_metadata(filename): 53 | content = distribution.get_metadata(filename) 54 | version_info = json.loads(content) 55 | 56 | return version_info 57 | 58 | version_info = get_distribution_version_info() 59 | 60 | version_installed = version_info['version'] 61 | 62 | 63 | author_name = "Ben Finney" 64 | author_email = "ben+python@benfinney.id.au" 65 | author = "{name} <{email}>".format(name=author_name, email=author_email) 66 | 67 | 68 | class YearRange: 69 | """ A range of years spanning a period. """ 70 | 71 | def __init__(self, begin, end=None): 72 | self.begin = begin 73 | self.end = end 74 | 75 | def __unicode__(self): 76 | text = "{range.begin:04d}".format(range=self) 77 | if self.end is not None: 78 | if self.end > self.begin: 79 | text = "{range.begin:04d}–{range.end:04d}".format(range=self) 80 | return text 81 | 82 | __str__ = __unicode__ 83 | 84 | 85 | def make_year_range(begin_year, end_date=None): 86 | """ Construct the year range given a start and possible end date. 87 | 88 | :param begin_date: The beginning year (text) for the range. 89 | :param end_date: The end date (text, ISO-8601 format) for the 90 | range, or a non-date token string. 91 | :return: The range of years as a `YearRange` instance. 92 | 93 | If the `end_date` is not a valid ISO-8601 date string, the 94 | range has ``None`` for the end year. 95 | 96 | """ 97 | begin_year = int(begin_year) 98 | 99 | try: 100 | end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d") 101 | except (TypeError, ValueError): 102 | # Specified end_date value is not a valid date. 103 | end_year = None 104 | else: 105 | end_year = end_date.year 106 | 107 | year_range = YearRange(begin=begin_year, end=end_year) 108 | 109 | return year_range 110 | 111 | copyright_year_begin = "2001" 112 | build_date = version_info['release_date'] 113 | copyright_year_range = make_year_range(copyright_year_begin, build_date) 114 | 115 | copyright = "Copyright © {year_range} {author} and others".format( 116 | year_range=copyright_year_range, author=author) 117 | license = "Apache-2" 118 | url = "https://pagure.io/python-daemon/" 119 | 120 | 121 | # Local variables: 122 | # coding: utf-8 123 | # mode: python 124 | # End: 125 | # vim: fileencoding=utf-8 filetype=python : 126 | -------------------------------------------------------------------------------- /demo/download/utils.c: -------------------------------------------------------------------------------- 1 | /********** 2 | * 3 | **********/ 4 | 5 | #include "utils.h" 6 | 7 | /**************************** 8 | * CGI Debug Log solution * 9 | ****************************/ 10 | // #define __EMBEDDED_PLATFORM /* 仅在嵌入式平台在编译运行时注释掉这一行。 */ 11 | #ifndef __EMBEDDED_PLATFORM 12 | const char *serverIP = "127.0.0.1"; // localhost. 13 | const int serverPort = 21919; // the default DebugLog server port. 14 | 15 | const int RET_SUCCESS = 0; 16 | const int RET_FAILURE = -1; 17 | 18 | int tcdbg_printf(char *message, int msg_len){ 19 | int sock = socket(PF_INET, SOCK_STREAM, 0); 20 | if ( sock==-1 ) return RET_FAILURE; 21 | 22 | struct sockaddr_in serv_addr; 23 | memset(&serv_addr, 0, sizeof(serv_addr)); 24 | serv_addr.sin_family = AF_INET; 25 | serv_addr.sin_addr.s_addr = inet_addr(serverIP); // IP: server ip 26 | serv_addr.sin_port = htons( serverPort ); 27 | 28 | if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 29 | return RET_FAILURE; 30 | 31 | int send_len = write(sock, message, msg_len); 32 | 33 | close(sock); 34 | 35 | return RET_SUCCESS; 36 | } 37 | 38 | 39 | void CGI_Println(const char *fmt, ...){ 40 | va_list ap; 41 | va_start(ap, fmt); 42 | 43 | char dbg_message[128] = {'\0'}; 44 | /*ret =*/ vsprintf(dbg_message, fmt, ap); 45 | 46 | tcdbg_printf(dbg_message, strlen(dbg_message)); 47 | 48 | va_end(ap); 49 | } 50 | #endif 51 | 52 | 53 | int dump_http_head(char *filename){ 54 | printf("Pragma: no-cache\n"); 55 | printf("Cache-control: no-cache\n"); 56 | printf("Content-type: application/octet-stream\n"); 57 | printf("Content-Transfer-Encoding: binary\n"); 58 | 59 | printf("Content-Disposition: attachment; filename=\"%s\"\n\n", 60 | filename); 61 | fflush(stdout); 62 | 63 | return 0; 64 | } 65 | 66 | int dump_http_FileStream(char *file_fullpath){ 67 | FILE *fp = NULL; 68 | 69 | if ((fp=fopen(file_fullpath, "rb"))==NULL){ 70 | // log error 71 | return ERR_DOWNLOAD_FAIL; 72 | } 73 | 74 | struct stat _fstat; 75 | if ( stat(file_fullpath, &_fstat) == -1 ){ 76 | // log error; 77 | return ERR_DOWNLOAD_FAIL; 78 | } 79 | 80 | char *download_buffer = NULL; 81 | long long read_size = 0; 82 | download_buffer = (char*)malloc(sizeof(char) * ((long long)_fstat.st_size + 1)); 83 | read_size = fread(download_buffer, sizeof(char), (long long)_fstat.st_size, fp); 84 | download_buffer[(long long)_fstat.st_size] = '\0'; 85 | if (read_size!=(long long)_fstat.st_size){ 86 | // log err; 87 | free(download_buffer); 88 | download_buffer = NULL; 89 | return ERR_DOWNLOAD_FAIL; 90 | } 91 | 92 | if (write(STDOUT_FILENO, download_buffer, (long long)_fstat.st_size) != (long long)_fstat.st_size){ 93 | // log error 94 | return ERR_DOWNLOAD_FAIL; 95 | } 96 | 97 | fflush(stdout); 98 | 99 | free(download_buffer); 100 | fclose(fp); 101 | 102 | return 0; 103 | } 104 | 105 | int prepare_download_file(){ 106 | /* 107 | char cmd[256] = {'\0'}; 108 | snprintf(cmd, 255, "tar zcvf %s -C /tmp/ heheda.txt", file_fullpath); 109 | 110 | // char tmp[256] = {'\0'}; 111 | // snprintf(tmp, 255, "echo '%s' > /dev/pts/5", cmd); 112 | // if((ret=system(tmp)) != 0){ 113 | if((ret=call_cmd("/bin/cat", 1, 1, "/tmp/heheda.txt")) != 0){ 114 | return ret; 115 | } 116 | 117 | ret = system(cmd); 118 | if (ret!=0){ 119 | return ret; 120 | } 121 | sleep(1); 122 | */ 123 | return 0; 124 | } 125 | 126 | 127 | // #define FILENAME "all_pids.tar.gz" 128 | // #define FILEPATH "/tmp/" 129 | 130 | // Test: 131 | #define FILENAME "test.png" 132 | #define FILEPATH "/tmp/" 133 | 134 | int handler_submit(void){ 135 | int ret = ERR_DOWNLOAD_FAIL; 136 | char file_fullpath[256] = {'\0'}; 137 | 138 | snprintf(file_fullpath, 255, "%s%s", FILEPATH, FILENAME); 139 | CGI_Println("file_fullpath: %s", file_fullpath); 140 | 141 | if ((ret = prepare_download_file()) == 0){ 142 | CGI_Println("prepare_download_file => ret: %d", ret); 143 | if ((ret = dump_http_head(FILENAME)) == 0){ 144 | CGI_Println("dump_http_head => ret: %d", ret); 145 | ret = dump_http_FileStream(file_fullpath); 146 | } 147 | // exit(ret); 148 | } 149 | CGI_Println("handler_submit return ret: %d", ret); 150 | return ret; 151 | } 152 | -------------------------------------------------------------------------------- /demo/download_a_file/download_a_file.c: -------------------------------------------------------------------------------- 1 | /***************************** 2 | * Build: 3 | * $ make all 4 | * 5 | * Install: 6 | * $ sudo make install 7 | * 8 | * Clean: 9 | * $ make clean 10 | * $ sudo rm -f /var/www/cgi-bin/*download_a_file.* 11 | * 12 | * Note: 13 | * you may need to run: 14 | * $ sudo ln -s /usr/include/x86_64-linux-gnu/sys/ /usr/include/sys 15 | * ### /\ example of Ubuntu 64bit /\ 16 | * 17 | ******************************/ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "cgic.h" 23 | 24 | #include 25 | #include 26 | 27 | #define STATUS_READY 0 28 | #define ERR_DOWNLOAD_FAIL -1 29 | 30 | int handler_display(int *); 31 | int handler_submit(void); 32 | 33 | int cgiMain(){ 34 | int ret = 0; 35 | int stat = STATUS_READY; 36 | 37 | typedef enum Act {ACT_INIT=0, DISPLAY, SUBMIT, Invalid} Act; 38 | Act act = ACT_INIT; 39 | int client_act = 0; 40 | 41 | cgiFormInteger("act", &client_act, (int)DISPLAY); 42 | act = (Act)client_act; 43 | 44 | switch(act){ 45 | case SUBMIT: 46 | stat = handler_submit(); 47 | return 0; 48 | case DISPLAY: 49 | handler_display(&stat); 50 | break; 51 | case Invalid: 52 | default: 53 | break; 54 | } 55 | return ret; 56 | } 57 | 58 | 59 | int handler_display(int *stat_p){ 60 | int ret = 0; 61 | 62 | if (*stat_p<0){ 63 | // pass 64 | } 65 | 66 | // cgiWriteEnvironment("/CHANGE/THIS/PATH/capcgi.dat"); 67 | cgiHeaderContentType("text/html"); 68 | 69 | char *html_file = "cgi_download_a_file.html"; 70 | 71 | FILE *fp = NULL; 72 | if ((fp = fopen(html_file, "r")) == NULL){ 73 | // LOG ERROR; 74 | return 1; 75 | } 76 | 77 | struct stat _fstat; 78 | if ( stat(html_file, &_fstat) == -1 ){ 79 | // log error; 80 | return 1; 81 | } 82 | // char html[10240] = {'\0'}; 83 | char *html = NULL; 84 | long long read_size = 0; 85 | html = (char*)malloc(sizeof(char) * ((long long)_fstat.st_size + 1)); 86 | read_size = fread(html, sizeof(char), (long long)_fstat.st_size, fp); 87 | html[(long long)_fstat.st_size] = '\0'; 88 | if (read_size!=(long long)_fstat.st_size){ 89 | // log err; 90 | free(html); 91 | html = NULL; 92 | return 1; 93 | } 94 | 95 | fprintf(cgiOut, "%s", html); 96 | 97 | fflush(stdout); 98 | 99 | 100 | free(html); 101 | fclose(fp); 102 | return ret; 103 | } 104 | 105 | 106 | #define FILENAME "index.html" 107 | #define FILEPATH "/var/www/html/" 108 | 109 | int handler_submit(void){ 110 | int ret = ERR_DOWNLOAD_FAIL; 111 | 112 | /* 113 | char cmd[256] = {'\0'}; 114 | snprintf(cmd, 255, "%s", "/bin/save_file"); 115 | ret = system(cmd); 116 | if (ret!=0){ 117 | // DPRINT(); 118 | return ret; 119 | } 120 | */ 121 | ret = 0; 122 | 123 | printf("Pragma: no-cache\n"); 124 | printf("Cache-control: no-cache\n"); 125 | printf("Content-type: application/octet-stream\n"); 126 | printf("Content-Transfer-Encoding: binary\n"); 127 | 128 | printf("Content-Disposition: attachment; filename=\"%s\"\n\n", 129 | FILENAME); 130 | fflush(stdout); 131 | 132 | FILE *fp = NULL; 133 | char file_fullpath[256] = {'\0'}; 134 | snprintf(file_fullpath, 255, "%s%s", FILEPATH, FILENAME); 135 | if ((fp=fopen(file_fullpath, "rb"))==NULL){ 136 | // log error 137 | return ERR_DOWNLOAD_FAIL; 138 | } 139 | 140 | struct stat _fstat; 141 | if ( stat(file_fullpath, &_fstat) == -1 ){ 142 | // log error; 143 | return ERR_DOWNLOAD_FAIL; 144 | } 145 | 146 | char *download_buffer = NULL; 147 | long long read_size = 0; 148 | download_buffer = (char*)malloc(sizeof(char) * ((long long)_fstat.st_size + 1)); 149 | read_size = fread(download_buffer, sizeof(char), (long long)_fstat.st_size, fp); 150 | download_buffer[(long long)_fstat.st_size] = '\0'; 151 | if (read_size!=(long long)_fstat.st_size){ 152 | // log err; 153 | free(download_buffer); 154 | download_buffer = NULL; 155 | return ERR_DOWNLOAD_FAIL; 156 | } 157 | 158 | if (write(STDOUT_FILENO, download_buffer, (long long)_fstat.st_size) != (long long)_fstat.st_size){ 159 | // log error 160 | return ERR_DOWNLOAD_FAIL; 161 | } 162 | 163 | fflush(stdout); 164 | 165 | free(download_buffer); 166 | fclose(fp); 167 | return ret; 168 | } 169 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # filename : Makefile 3 | # author : Joseph Lin 4 | # E-mail : joseph.lin@aliyun.com 5 | # 6 | # reference: 《GNU make 项目管理》 - CH6 7 | # 8 | ### 9 | ### 2018/Jul/08 add CGIDebugLogc lib 10 | ### 11 | 12 | ### 13 | ### program tree: 14 | ### DebugLog_solution/ 15 | ### |-- Makefile 16 | ### |-- LINUX-C_daemon/ 17 | ### | |--- Makefile 18 | ### | `-- ## source code to build libbecome_daemon.a 19 | ### |-- lib/ 20 | ### | |-- become_daemon/ 21 | ### | | |-- Makefile ## 调用 LINUX-C_daemon/ 下的Makefile 22 | ### | | `- ## 将会copy *.a 到这里 23 | ### | |-- CGIUtils/ 24 | ### | | |-- Makefile 25 | ### | `-- echo2tmnl/ 26 | ### | |-- Makefile 27 | ### | 28 | ### |-- test_src/ ## 可以 build 运行成功, 但是在本应用环境下,这个位置的program 没有用。 29 | ### | |-- Makefile ## build test_become_daemon* 出来! 30 | ### | `-- test_become_daemon.c 31 | ### | 32 | ### |-- src/ ## <== $(CGIDebugLog) 33 | ### | |-- Makefile 34 | ### | | 35 | ### | |-- CGIDebugLogd/ 36 | ### | | |-- daemonEcho2.c 37 | ### | | |-- CGIDebugLogd.py 38 | ### | | `- Makefile 39 | ### | |-- socketClient.py 40 | ### | | 41 | ### | `- CGIDebugLogc/ 42 | ### | |-- CGIDebugLogc.c 43 | ### | |-- CGIDebugLogc.h 44 | ### | |-- Makefile ## build out libCGIDebugLogc.a 45 | ### | `- Examples/main.c 46 | ### | 47 | ### `- others. 48 | ### 49 | ### /makefile 将分别调用 lib/become_daemon/Makefile 和 src/Makefile 50 | ### 51 | 52 | COPY=cp 53 | MOVE=mv 54 | 55 | ### 56 | ### ":=" 这个符号的含义!??? 57 | ### 58 | lib_become_daemon := lib/become_daemon 59 | lib_CGIUtils := lib/CGIUtils 60 | lib_echo2tmnl := lib/echo2tmnl 61 | 62 | ### 63 | ### usage LINUX-C_daemon 64 | ### 65 | # libraries := $(lib_become_daemon) $(lib_CGIUtils) $(lib_echo2tmnl) 66 | 67 | ### 68 | ### usage python-daemon 69 | ### 70 | libraries := $(lib_CGIUtils) $(lib_echo2tmnl) 71 | ## Note: python-daemon/Reference/pipy@python-daemon/python-daemon-2.1.2.tar.gz 72 | 73 | 74 | CGIDebugLog:= src 75 | 76 | .PHONY: all $(CGIDebugLog) $(libraries) install clean 77 | 78 | ### 79 | ### usage LINUX-C_daemon 80 | ### 81 | # all: $(CGIDebugLog) 82 | # cp $(CGIDebugLog)/daemonEcho2 $(CGIDebugLog)/CGIDebugLogd.py ./bin/ 83 | # cp $(CGIDebugLog)/libCGIDebugLogc.a ./bin/ 84 | # @echo "======= DebugLog_solution/ build finish ===========\n" 85 | 86 | ### 87 | ### usage python-daemon 88 | ### 89 | all: $(CGIDebugLog) 90 | $(MOVE) $(CGIDebugLog)/DaemonEcho2 $(CGIDebugLog)/CGIDebugLogd.py ./bin/ 91 | $(MOVE) $(CGIDebugLog)/libCGIDebugLogc.a ./bin/ 92 | @echo "======= DebugLog_solution/ build finish ===========\n" 93 | 94 | 95 | 96 | ### 97 | ### 应用程序 与 库链接 的依存关系 98 | ### 99 | $(CGIDebugLog): $(libraries) 100 | $(MAKE) --directory=$@ 101 | @echo "---- $(CGIDebugLog) build finish -----\n" 102 | 103 | $(libraries): 104 | $(MAKE) --directory=$@ 105 | @echo "---- $(libraries) build finish -----\n" 106 | ### 107 | ### ^ 以上,调用了 test_basic_daemon/Makefile 108 | ### 和 调用了 lib/become_daemon/Makefile 109 | ### 110 | 111 | 112 | install: 113 | $(MAKE) --directory=$(lib_CGIUtils) install 114 | $(MAKE) --directory=$(lib_echo2tmnl) install 115 | 116 | ##### $ make clean 将会是一个问题 ##### 117 | clean: 118 | $(MAKE) --directory=$(CGIDebugLog) clean && echo "\n" 119 | # $(MAKE) --directory=$(libraries) clean 120 | ### 121 | ### usage LINUX-C_daemon 122 | ### 123 | # $(MAKE) --directory=$(lib_become_daemon) clean && echo "\n" 124 | $(MAKE) --directory=$(lib_CGIUtils) clean && echo "\n" 125 | $(MAKE) --directory=$(lib_echo2tmnl) clean && echo "\n" 126 | rm -f ./bin/* 127 | 128 | 129 | clean_all: 130 | $(MAKE) --directory=$(CGIDebugLog) clean && echo "\n" 131 | # $(MAKE) --directory=$(libraries) clean 132 | ### 133 | ### usage LINUX-C_daemon 134 | ### 135 | # $(MAKE) --directory=$(lib_become_daemon) clean && echo "\n" 136 | $(MAKE) --directory=$(lib_CGIUtils) clean && echo "\n" 137 | $(MAKE) --directory=$(lib_echo2tmnl) clean && echo "\n" 138 | rm -f ./bin/* 139 | 140 | ## help - The default goal 141 | MAKE = make 142 | AWK = awk 143 | SORT = sort 144 | PR = pr 145 | help: 146 | @ $(MAKE) --print-data-base --question | \ 147 | $(AWK) '/^[^.%][-A-Za-z0-9_]*:/ \ 148 | { print substr($$1, 1, length($$1)-1) }' | \ 149 | $(SORT) | \ 150 | $(PR) --omit-pagination --width=80 --columns=4 151 | 152 | 153 | -------------------------------------------------------------------------------- /libraries/DebugLog_solution/test_lib_of_become_daemon/test_become_daemon.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU General Public License as published by the * 6 | * Free Software Foundation, either version 3 or (at your option) any * 7 | * later version. This program is distributed without any warranty. See * 8 | * the file COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Supplementary program for Chapter 37 */ 12 | 13 | /* test_become_daemon.c 14 | 15 | Test our becomeDaemon() function. 16 | */ 17 | #if 0 18 | #include "become_daemon.h" 19 | #include "./include/tlpi_hdr.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include /* STDIN_FILENO - 0, STDOUT_FILENO - 1, STDERR_FILENO - 2; 25 | * reference: ch3 &3.2 26 | * */ 27 | #include /* int open(); */ 28 | 29 | #include 30 | 31 | int 32 | main(int argc, char *argv[]) 33 | { 34 | int fd_out = open("/dev/tty", O_RDWR); 35 | printf("fd_out = %d\n", fd_out); 36 | if (fd_out == -1) 37 | { /* 'fd' -1 open fail */ 38 | 39 | exit(1); 40 | } 41 | char buff[128] = {'\0'}; 42 | snprintf(buff, sizeof(buff), "hello world\n"); 43 | write(fd_out, buff, strlen(buff)); 44 | close(fd_out); 45 | 46 | #if 0 47 | becomeDaemon(0); 48 | #else 49 | int flags = 0; 50 | int maxfd, fd; 51 | 52 | switch (fork()) { /* Become background process */ 53 | case -1: 54 | return -1; 55 | case 0: 56 | break; /* Child falls through... */ 57 | default: 58 | _exit(EXIT_SUCCESS); /* while parent terminates */ 59 | } 60 | 61 | if (setsid() == -1) /* Become leader of new session */ 62 | return -1; 63 | 64 | switch (fork()) { /* Ensure we are not session leader */ 65 | case -1: 66 | return -1; 67 | case 0: 68 | break; 69 | default: 70 | _exit(EXIT_SUCCESS); 71 | } 72 | 73 | if (!(flags & BD_NO_UMASK0)) 74 | umask(0); /* Clear file mode creation mask */ 75 | 76 | if (!(flags & BD_NO_CHDIR)) 77 | chdir("/"); /* Change to root directory */ 78 | 79 | if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */ 80 | maxfd = sysconf(_SC_OPEN_MAX); 81 | if (maxfd == -1) /* Limit is indeterminate... */ 82 | maxfd = BD_MAX_CLOSE; /* so take a guess */ 83 | 84 | for (fd = 0; fd < maxfd; fd++) 85 | close(fd); 86 | } 87 | 88 | if (!(flags & BD_NO_REOPEN_STD_FDS)) { 89 | close(STDIN_FILENO); /* Reopen standard fd's to /dev/null */ 90 | 91 | fd = open("/dev/null", O_RDWR); 92 | 93 | if (fd != STDIN_FILENO) /* 'fd' should be 0 */ 94 | return -1; 95 | if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) 96 | return -1; 97 | if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) 98 | return -1; 99 | } 100 | #endif 101 | /* Normally a daemon would live forever; we just sleep for a while */ 102 | sleep ( 5 ); 103 | 104 | fd_out = open("/dev/tty", O_RDWR); 105 | //printf("fd = %d\n", fd_out); 106 | if (fd_out == -1) 107 | { /* 'fd' -1 open fail */ 108 | // 当初在写 web 开发的库的时候,有试过 *.cgi 进程打开 tty 向某个终端输出, 但是失败了, 109 | // 这里出现的现象一定是一样的,因为都是 daemon 进程, 所以刚刚没有想到这一点是我的错! 110 | // 这里应该通过写文件 log 的方式来输出信息。至于想要输出到 tty? 还有待学习研究。 111 | exit(1); 112 | } 113 | snprintf ( buff, sizeof(buff), "hello daemon\n" ); 114 | write(fd_out, buff, strlen(buff)); 115 | close(fd_out); 116 | 117 | sleep((argc > 1) ? getInt(argv[1], GN_GT_0, "sleep-time") : 20); 118 | 119 | 120 | 121 | exit(EXIT_SUCCESS); 122 | } 123 | 124 | #else 125 | #include "become_daemon.h" 126 | #include "tlpi_hdr.h" 127 | 128 | void run(); 129 | 130 | int 131 | main(int argc, char *argv[]) 132 | { 133 | becomeDaemon(0); 134 | 135 | /* Normally a daemon would live forever; we just sleep for a while */ 136 | run(); 137 | // sleep((argc > 1) ? getInt(argv[1], GN_GT_0, "sleep-time") : 20); 138 | 139 | exit(EXIT_SUCCESS); 140 | 141 | } 142 | 143 | void run(){ 144 | FILE *pf = fopen("/tmp/foo.daemon", "at+"); 145 | if (pf == NULL) 146 | { 147 | exit(1); 148 | } 149 | char buff[256] = {'\0'}; 150 | while (1) 151 | { 152 | memset(buff, '\0', sizeof(buff)); 153 | fgets(buff, sizeof(buff), pf); // move fseek piont to the end of file. 154 | fprintf(pf, "heheda\n"); 155 | 156 | sleep(5); 157 | } 158 | fclose(pf); 159 | } 160 | #endif -------------------------------------------------------------------------------- /src/getEnvir.c: -------------------------------------------------------------------------------- 1 | /** 2 | * file name: getEnvir.c 3 | * Author : Joseph Lin 4 | * E-mail : joseph.lin@aliyun.com 5 | * 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "cgic.h" 14 | #include "CGIDebugLogc.h" 15 | #include "flate.h" 16 | 17 | /** 18 | * functions define: 19 | */ 20 | 21 | 22 | /** 23 | * Global variables: 24 | */ 25 | int doDebug = 1; 26 | 27 | /* ./var/www/cgi-bin/ -> ../ ==> ./var/www/environment-variables.html */ 28 | #define HTML_PATH "../environment-variables.html" 29 | 30 | #define HEADER_ZONE "header_env_zone" 31 | #define JAVASCRIPT_ZONE "javascript_env_zone" 32 | #define FORM_ZONE "form_env_zone" 33 | 34 | 35 | int show_head( char *tplName ); 36 | int show_javascript( char *tplName ); 37 | int show_form( char *tplName ); 38 | 39 | int showHTML(); 40 | 41 | 42 | 43 | /** 44 | * running logical: 45 | */ 46 | int cgiMain(int argc, char *argv[]) 47 | { 48 | CGIPrint("\nrunning cgiMain()\n"); 49 | 50 | // CGIPrint("\n --- now try to get Browser Request METHOD ----"); 51 | 52 | // char method[30] = {0}; 53 | // if(getenv("REQUEST_METHOD")) { 54 | // strcpy(method, getenv("REQUEST_METHOD")); 55 | // } 56 | // CGIPrint("[Debug] > Request METHOD is: %s", method); 57 | 58 | 59 | // if(strcmp(method,"POST") == 0) { //REQUEST_METHOD = POST 60 | // return 1; 61 | // } 62 | 63 | CGIPrint( "HTTP head" ); 64 | // HTTP head 65 | //printf("\n") 66 | 67 | printf("\n"); 68 | 69 | CGIPrint( "HTTP Contents 👇"); 70 | showHTML(); 71 | 72 | CGIPrint( "==== CGI END! ======"); 73 | 74 | return 0; 75 | } 76 | 77 | 78 | int show_head( char *tplName ){ 79 | 80 | CGIPrint( "\n running show_head()\n"); 81 | 82 | templateSetFile(tplName); CGIPrint ("\t templateSetFile(tplName); finish! \n"); 83 | 84 | templateSetVar( HEADER_ZONE, ""); CGIPrint ("\t templateSetVar( HEADER_ZONE , \"\"); finish\n"); 85 | 86 | 87 | ///// database 88 | // char menuType[32] = {0}; 89 | // tcapi_get("WebCurSet_Entry", "menuType", menuType); 90 | // templateSetVar("menuType", menuType); 91 | //templateSetVar("", ""); 92 | 93 | templatePrint(); CGIPrint("\t templatePrint(); finish\n"); 94 | templateFreeMem(); CGIPrint ( "\t templateFreeMem(); finish\n"); 95 | 96 | return 0; 97 | } 98 | 99 | int showHTML(){ 100 | show_head(HTML_PATH); 101 | show_javascript(HTML_PATH); 102 | show_form(HTML_PATH); 103 | return 0; 104 | } 105 | 106 | int show_javascript( char *tplName ){ 107 | templateSetFile( tplName ); 108 | templateSetVar ( JAVASCRIPT_ZONE, ""); 109 | 110 | //// database 111 | // char pwd[128] = {0}; 112 | // tcapi_get("Info_devDefInf", "Password0", pwd); 113 | // templateSetVar("Password0", pwd); 114 | //templateSetVar("", ""); 115 | 116 | 117 | templatePrint (); 118 | templateFreeMem(); 119 | } 120 | 121 | 122 | int show_form( char *tplName ){ 123 | templateSetFile( tplName ); 124 | templateSetVar ( FORM_ZONE, ""); 125 | 126 | //// database 127 | // char menuType[32] = {0}; 128 | 129 | // tcapi_get("WebCurSet_Entry", "menuType", menuType); 130 | // templateSetVar("menuType", menuType); 131 | // HTTP contents 132 | 133 | templateSetVar("v_port", getenv("SERVER_PORT") ); //printf( "\t\t
  • %-30s : %s
  • \n", "SERVER_PORT", getenv("SERVER_PORT") ); 134 | templateSetVar("v_serverName", getenv("SERVER_NAME") ); //printf( "\t\t
  • %-30s : %s
  • \n", "SERVER_NAME", getenv("SERVER_NAME") ); 135 | templateSetVar("v_reqHost", getenv("HTTP_HOST") ); //printf( "\t\t
  • %-30s : %s
  • \n", "HTTP_HOST", getenv("HTTP_HOST") ); 136 | templateSetVar("v_reqMethod", getenv("REQUEST_METHOD") ); //printf( "\t\t
  • %-30s : %s
  • \n", "REQUEST_METHOD", getenv("REQUEST_METHOD") ); 137 | templateSetVar("v_serverProtocol", getenv("SERVER_PROTOCOL") ); //printf( "\t\t
  • %-30s : %s
  • \n", "SERVER_PROTOCOL", getenv("SERVER_PROTOCOL") ); 138 | templateSetVar("v_serverSoftware", getenv("SERVER_SOFTWARE") ); //printf( "\t\t
  • %-30s : %s
  • \n", "SERVER_SOFTWARE", getenv("SERVER_SOFTWARE") ); 139 | templateSetVar("v_userAgent", getenv("HTTP_USER_AGENT") ); //printf( "\t\t
  • %-30s : %s
  • \n", "HTTP_USER_AGENT", getenv("HTTP_USER_AGENT") ); 140 | templateSetVar("v_gatewayInterface", getenv("GATEWAY_INTERFACE") ); //printf( "\t\t
  • %-30s : %s
  • \n", "GATEWAY_INTERFACE ", getenv("GATEWAY_INTERFACE ") ); 141 | templateSetVar("v_PATH", getenv("PATH") ); //printf( "\t\t
  • %-30s : %s
  • \n", "PATH", getenv("PATH") ); 142 | templateSetVar("v_scriptName", getenv("SCRIPT_NAME") ); //printf( "\t\t
  • %-30s : %s
  • \n", "SCRIPT_NAME", getenv("SCRIPT_NAME") ); 143 | templateSetVar("v_remoteAddr", getenv("REMOTE_ADDR") ); //printf( "\t\t
  • %-30s : %s
  • \n", "REMOTE_ADDR", getenv("REMOTE_ADDR") ); 144 | templateSetVar("v_libPATH", getenv("LD_LIBRARY_PATH") ); //printf( "\t\t
  • %-30s : %s
  • \n", "LD_LIBRARY_PATH", getenv("LD_LIBRARY_PATH") ); 145 | 146 | 147 | 148 | templatePrint(); 149 | templateFreeMem(); 150 | } 151 | -------------------------------------------------------------------------------- /Luci-of-OpenWrt/README.md: -------------------------------------------------------------------------------- 1 | # OpenWrt Web GUI Develop 2 | 3 | ==因为个人的水平和精力是有限的,如果本目录下的内容存在错误,疏忽之处,欢迎指出:可创建 Issue 或者 fork 修改后向本仓库做 pull request== 4 | 5 | [TOC] 6 | 7 | ----- 8 | 9 | ## 理解 Luci 架构 10 | 11 | > 注: 12 | > 13 | > 下文“几个元素”中,属于“总结”。 14 | > 15 | > 是在编写本文是为了理清思路,边整理思路边写下的。 16 | > 17 | > 若有不明之处可以在看完本目录下的内容之后再回过头来看一遍。 18 | 19 | 几个元素: 20 | 21 | - 在 OpenWrt 使用 Luci -- Web。 22 | 23 | - Luci 使用 lua 语言作为后台。 24 | 25 | - Luci 使用 lua 通过 uci 库读取和修改 OpenWrt 协定的 UCI 配置文件。 26 | 27 | - OpenWrt 内协定 UCI 配置文件,并提供了不同的接口操作它,其中之一是实现了 lua 语言的 uci 库。 28 | 29 | - Luci 框架内基于 lua + uci 库编写了 CBI 框架 -- CBI 框架是 Luci 的子框架。 30 | 31 | - CBI 框架加载入 uci 配置文件相应的 lua 模块,对于 HTTP GET 能够以 CBI 框架的运行逻辑将 UCI 配置文件转化渲染成用于 Web 前端显示的 HTML 做 HTTP Response;同样对 HTTP POST 也以 CBI 框架运行的逻辑将 form 表单修改写入到 UCI 配置文件中(和生效)。 32 | 33 | - 由于 UCI 有着规范的格式,以及 CBI 框架的 OOP 实现,我们不需要从头如 读取 UCI 配置文件,写出如何渲染成 HTML 的代码再 Response 到 Client(浏览器);这些操作是可以抽象出来的一套可重用的参数和运行逻辑(方法),用户(promgramer)只需要编写针对细分的不同的配置文件内容的 CBI 模块代码即可(即,OOP 中的 class 已经被实现好了,只需要根据不同的实体内容实例和调整实例内容即可)。 34 | 35 | - 因为 CBI 框架的高度可重用性(配置文件大同小异,用户(user)管理网页风格统一),所以我们可以设想只要在编写的 CBI 模块代码中指明该模块关联的 UCI 配置文件,那么 CBI 框架就能够将该 UCI 配置文件以写好的有限的规则读取出来并显示在浏览器上 -- 但是因为我们需要控制配置文件中的哪些部分需要显示,哪些部分不需要显示;哪些部分以何种方式显示,另一些部分又以另外的什么方式显示;所以我们除了声明配置文件外,还需要声明这些内容 -- 这很类似“声明式”编程,后面具体会感觉到。 36 | 37 | (另外一提,这点和 Web 开发的后台管理网站没有本质区别,后台管理网站也是通过编写大量通用的代码涵盖大范围的内容类型(数据库,数据 type)以做到对大部分编写的数据模型无需额外编写管理页面,直接能够以通用的模板显示出来并且能够操作) 38 | 39 | - Luci 框架亦是 MVC 模式,其中 CBI 即是 model,因为用户(user)管理网页(路由器的 Web GUI)没有很多花样,所以基本上需要的前端模板 luci 都提供了 -- 即用户编写了 CBI 模块即可,CBI 框架渲染时的运行逻辑能够使用既有的模板为浏览器提供 HTML 显示。当然,在一些需要以特殊方式显示或者提供更丰富的功能的地方,我们仍然可以自己编写模板(view),然后在 CBI 内指定哪些 UCI 内容使用该模板显示。 40 | 41 | - Luci 框架的控制器是理解 Luci 框架运行逻辑的关键,它主要将用户编写的控制器规则生成 URI(路由)(并且提供了反向解析的接口),用户(user)只需要在浏览器访问 URL,Luci 就能够通过控制器执行程序中定义的处理代码(比如 CBI 模块)得到处理代码(方法)的返回内容作为 HTTP 响应(View),即 controller -> model -> view(view 中又包含 controller URL)。 42 | 43 | 44 | 45 | **详解 Luci 框架** -- 将分以下步骤进行(可以仔细看一下,有助于理清思路): 46 | 47 | 1. 软件结构:源码结构和运行结构 48 | 1. 源码分布介绍和“安装/运行”文件分布 49 | 2. 源码编译/打包方式和上传安装 50 | 2. HTTP Server 51 | 1. HTTP Server 和 Luci 交互基本原理 52 | 2. HTTP Server 简单介绍 53 | 3. Luci 用户系统 54 | 1. 多用户支持 55 | 2. 状态保持原理(HTTP 是无状态协议) 56 | 3. 登录系统 57 | 4. Luci 框架 58 | 1. hello world 级 demo -- 接触与感受 59 | 2. MVC 简介 60 | 3. Controller 和 URI 61 | 4. View -- 模板简介和基本使用/语法 62 | 5. Luci 框架前半部运行逻辑 63 | 1. 从 HTTP Server 到执行 Luci 64 | 2. 从 Luci 入口到 Controller 65 | 3. 从 Controller 到执行 target(函数) 66 | 6. 非 CBI target -- call 与 template 实例 67 | 7. Model(模型 )-- CBI 框架 68 | 1. CBI 的 hello world 级 demo 69 | 2. 了解 OOP 基本知识和作用 70 | 1. 基本知识 71 | 2. 基本作用 -> 可实现的声明式编程 72 | 3. 加速编程的好处,隐藏大量细节的坏处 73 | 4. lua OOP 语法与动态语法 74 | 5. 类与实例 -- 不容模糊的 `self` 75 | 3. UCI 协议(约定) 76 | 1. 配置文件格式 77 | 2. 常规对应 Web 页面显示的控件 78 | 3. lua 中的 uci 库与 API 79 | 4. CBI 模块实例 - example 页和 example 配置文件 80 | 5. 处理表单 -- 探究 CBI 框架运行逻辑 81 | 1. 模块,节,tab 与 option 82 | 2. 基本类型和动态绑定(组合模式) 83 | 3. lua 脚本代码在什么时候运行?以及 require 和 loader 区别 84 | 4. 运行方法(代码执行逻辑)和重写 85 | 5. 可选的定制化 -- 钩子函数 86 | 6. 配置更新的生效和重定向 87 | 8. 模板扩展 -- javascript 异步请求 88 | 5. 节选 - 编程关键词与理解 89 | 1. 类,类型,实例,对象 90 | 2. API,框架,模块,(数据)模型 91 | 3. 钩子,重写 92 | 4. 强类型和弱类型,动态和静态 93 | 5. 面向过程,面向对象,面向声明 94 | 6. UML 95 | 96 | 97 | 98 | 99 | 100 | > 注: 101 | > 102 | > 因为本目录的内容并没有按照上文“步骤”写完,所以只称得上“粗解”。 103 | > 104 | > 因为 PPT 是先于本文做完的,虽然 PPT 内容本身可能不够精细,但是根据 PPT 内的文字说明,讲解,结合 Luci 源码查看,想必对框架理解会有一定的帮助。 105 | > 106 | > 另外在写 PPT 的时候是为了团队现场讲解,会配置打开的源代码文件讲,所以在 PPT 中主要以概括性、解释性、总结性内容为主,读者需要结合源码看。此处内容后面可能会不定期更新。 107 | > 108 | > 本着不等将事情做到完美的那一刻再分享出来的理由, 109 | > 110 | > > 因为一是这样会过很久之后才分享出来,二是有可能做不到心目中的完美而一直不能分享出来。 111 | > 112 | > 若是有需要的读者早一些看到,并且可能能起到一定的帮助,再由读者自身通过结合源码以及翻阅资料补充便可以理解 Luci 框架。那么本目录下分享出来的内容便是有用的。 113 | > 114 | > 通过我也期望于即使目前此处的内容还很粗糙,但是若有读者能够 fork > 编辑补重小节小段或者是几句话,几行代码解释介绍,那也是甚好的。 115 | 116 | 粗解 Luci 框架: 117 | 118 | ### 目录 119 | 120 | 1. 软件结构:源码结构和运行结构 121 | 1. 源码分布介绍和“安装/运行”文件分布 122 | 2. 源码编译/打包方式和上传安装 123 | 2. HTTP Server 124 | 1. HTTP Server 和 Luci 交互基本原理 125 | 2. HTTP Server 简单介绍 126 | 3. Luci 用户系统 《== 未完成 127 | 1. 多用户支持 128 | 2. 状态保持原理(HTTP 是无状态协议) 129 | 3. 登录系统 130 | 4. Luci 框架 131 | 1. hello world 级 demo -- 接触与感受 132 | 2. MVC 简介 133 | 3. Controller 和 URI 134 | 4. View -- 模板简介和基本使用/语法 135 | 5. Luci 框架前半部运行逻辑《== 参见 [luci框架代码”逻辑”流程图.pdf](luci框架代码"逻辑"流程图.pdf) 136 | 1. 从 HTTP Server 到执行 Luci 137 | 2. 从 Luci 入口到 Controller 138 | 3. 从 Controller 到执行 target(函数) 139 | 6. 非 CBI target -- call 与 template 实例 140 | 7. Model(模型 )-- CBI 框架 141 | 1. CBI 的 hello world 级 demo 142 | 2. 了解 OOP 基本知识和作用《== 未完成 143 | 1. 基本知识 144 | 2. 基本作用 -> 可实现的声明式编程 145 | 3. 加速编程的好处,隐藏大量细节的坏处 146 | 4. lua OOP 语法与动态语法 147 | 5. 类与实例 -- 不容模糊的 `self` 148 | 3. UCI 协议(约定) 149 | 1. 配置文件格式 150 | 2. 常规对应 Web 页面显示的控件 151 | 3. lua 中的 uci 库与 API《== 未完成 152 | 4. CBI 模块实例 - example 页和 example 配置文件 153 | 1. 模块,节,tab 与 option 154 | 2. 基本类型和动态绑定(组合模式)《== 未完成 155 | 3. input-Value,select-ListValue,checkbox-Flag 156 | 5. 处理表单 -- 探究 CBI 框架运行逻辑 157 | 1. lua 脚本代码在什么时候运行?以及 require 和 loader 区别《== 未完成 158 | 2. 运行方法(代码执行逻辑)和重写 159 | 3. 可选的定制化 -- 钩子函数《== 未完成 160 | 4. 配置更新的生效和重定向 161 | 8. 模板扩展 -- javascript 异步请求《== 未完成 162 | 5. 节选 - 编程关键词与理解《== 未完成 163 | 1. 类,类型,实例,对象 164 | 2. API,框架,模块,(数据)模型 165 | 3. 钩子,重写 166 | 4. 强类型和弱类型,动态和静态 167 | 5. 面向过程,面向对象,面向声明 168 | 6. UML 169 | 170 | 171 | 172 | ### 正文 173 | 174 | 参阅 [luci-web(GUI)-for-develop.pptx](luci-web(GUI)-for-develop.pptx) -------------------------------------------------------------------------------- /libraries/DebugLog_solution/LINUX-C_daemon/src/error_functions.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2015. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute it * 5 | * under the terms of the GNU Lesser General Public License as published * 6 | * by the Free Software Foundation, either version 3 or (at your option) * 7 | * any later version. This program is distributed without any warranty. * 8 | * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * 9 | \*************************************************************************/ 10 | 11 | /* Listing 3-3 */ 12 | 13 | /* error_functions.c 14 | 15 | Some standard error handling routines used by various programs. 16 | */ 17 | #include 18 | #include "error_functions.h" 19 | #include "tlpi_hdr.h" 20 | #include "../lib/ename.c.inc" /* Defines ename and MAX_ENAME */ 21 | 22 | #ifdef __GNUC__ /* Prevent 'gcc -Wall' complaining */ 23 | __attribute__ ((__noreturn__)) /* if we call this function as last */ 24 | #endif /* statement in a non-void function */ 25 | static void 26 | terminate(Boolean useExit3) 27 | { 28 | char *s; 29 | 30 | /* Dump core if EF_DUMPCORE environment variable is defined and 31 | is a nonempty string; otherwise call exit(3) or _exit(2), 32 | depending on the value of 'useExit3'. */ 33 | 34 | s = getenv("EF_DUMPCORE"); 35 | 36 | if (s != NULL && *s != '\0') 37 | abort(); 38 | else if (useExit3) 39 | exit(EXIT_FAILURE); 40 | else 41 | _exit(EXIT_FAILURE); 42 | } 43 | 44 | /* Diagnose 'errno' error by: 45 | 46 | * outputting a string containing the error name (if available 47 | in 'ename' array) corresponding to the value in 'err', along 48 | with the corresponding error message from strerror(), and 49 | 50 | * outputting the caller-supplied error message specified in 51 | 'format' and 'ap'. */ 52 | 53 | static void 54 | outputError(Boolean useErr, int err, Boolean flushStdout, 55 | const char *format, va_list ap) 56 | { 57 | #define BUF_SIZE 500 58 | char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE]; 59 | 60 | vsnprintf(userMsg, BUF_SIZE, format, ap); 61 | 62 | if (useErr) 63 | snprintf(errText, BUF_SIZE, " [%s %s]", 64 | (err > 0 && err <= MAX_ENAME) ? 65 | ename[err] : "?UNKNOWN?", strerror(err)); 66 | else 67 | snprintf(errText, BUF_SIZE, ":"); 68 | 69 | snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg); 70 | 71 | if (flushStdout) 72 | fflush(stdout); /* Flush any pending stdout */ 73 | fputs(buf, stderr); 74 | fflush(stderr); /* In case stderr is not line-buffered */ 75 | } 76 | 77 | /* Display error message including 'errno' diagnostic, and 78 | return to caller */ 79 | 80 | void 81 | errMsg(const char *format, ...) 82 | { 83 | va_list argList; 84 | int savedErrno; 85 | 86 | savedErrno = errno; /* In case we change it here */ 87 | 88 | va_start(argList, format); 89 | outputError(TRUE, errno, TRUE, format, argList); 90 | va_end(argList); 91 | 92 | errno = savedErrno; 93 | } 94 | 95 | /* Display error message including 'errno' diagnostic, and 96 | terminate the process */ 97 | 98 | void 99 | errExit(const char *format, ...) 100 | { 101 | va_list argList; 102 | 103 | va_start(argList, format); 104 | outputError(TRUE, errno, TRUE, format, argList); 105 | va_end(argList); 106 | 107 | terminate(TRUE); 108 | } 109 | 110 | /* Display error message including 'errno' diagnostic, and 111 | terminate the process by calling _exit(). 112 | 113 | The relationship between this function and errExit() is analogous 114 | to that between _exit(2) and exit(3): unlike errExit(), this 115 | function does not flush stdout and calls _exit(2) to terminate the 116 | process (rather than exit(3), which would cause exit handlers to be 117 | invoked). 118 | 119 | These differences make this function especially useful in a library 120 | function that creates a child process that must then terminate 121 | because of an error: the child must terminate without flushing 122 | stdio buffers that were partially filled by the caller and without 123 | invoking exit handlers that were established by the caller. */ 124 | 125 | void 126 | err_exit(const char *format, ...) 127 | { 128 | va_list argList; 129 | 130 | va_start(argList, format); 131 | outputError(TRUE, errno, FALSE, format, argList); 132 | va_end(argList); 133 | 134 | terminate(FALSE); 135 | } 136 | 137 | /* The following function does the same as errExit(), but expects 138 | the error number in 'errnum' */ 139 | 140 | void 141 | errExitEN(int errnum, const char *format, ...) 142 | { 143 | va_list argList; 144 | 145 | va_start(argList, format); 146 | outputError(TRUE, errnum, TRUE, format, argList); 147 | va_end(argList); 148 | 149 | terminate(TRUE); 150 | } 151 | 152 | /* Print an error message (without an 'errno' diagnostic) */ 153 | 154 | void 155 | fatal(const char *format, ...) 156 | { 157 | va_list argList; 158 | 159 | va_start(argList, format); 160 | outputError(FALSE, 0, TRUE, format, argList); 161 | va_end(argList); 162 | 163 | terminate(TRUE); 164 | } 165 | 166 | /* Print a command usage error message and terminate the process */ 167 | 168 | void 169 | usageErr(const char *format, ...) 170 | { 171 | va_list argList; 172 | 173 | fflush(stdout); /* Flush any pending stdout */ 174 | 175 | fprintf(stderr, "Usage: "); 176 | va_start(argList, format); 177 | vfprintf(stderr, format, argList); 178 | va_end(argList); 179 | 180 | fflush(stderr); /* In case stderr is not line-buffered */ 181 | exit(EXIT_FAILURE); 182 | } 183 | 184 | /* Diagnose an error in command-line arguments and 185 | terminate the process */ 186 | 187 | void 188 | cmdLineErr(const char *format, ...) 189 | { 190 | va_list argList; 191 | 192 | fflush(stdout); /* Flush any pending stdout */ 193 | 194 | fprintf(stderr, "Command-line usage error: "); 195 | va_start(argList, format); 196 | vfprintf(stderr, format, argList); 197 | va_end(argList); 198 | 199 | fflush(stderr); /* In case stderr is not line-buffered */ 200 | exit(EXIT_FAILURE); 201 | } 202 | -------------------------------------------------------------------------------- /lib/flate-1.4.6/README: -------------------------------------------------------------------------------- 1 | FLATE Library (Fast Template 1.4.6) 2 | (c) Fabien MENEMENLIS (nihilist@dead-inside.org) 3 | 4 | This program is released under the LGPL License. For copying information 5 | see the file COPYING. 6 | Note that the 1.4 version is just a license change: it is now covered by 7 | the Lesser General Public License and not by the GPL anymore, due to evident 8 | constraints pointed to me by some users. 9 | 1.4.4 has a few bug fixes over 1.4.3 (mostly with multiple zones / tables) 10 | 1.4.5 does a better job at parsing/checking buggy templates (checktpl) 11 | 1.4.6 is an important fix regarding memory overlaps due to a rewrite of the 12 | memcpy() function in newer glibc (thanx to Gerry Marthe for pointing it out) 13 | 14 | 15 | 1. What is it all about? 16 | 17 | FLATE is a library used in cgi applications to deal with html files organized 18 | as templates. The goal is to avoid any html code in the application. All 19 | changes to the html pages produced is made through functions, able to deal 20 | with complex tables and zones. Thus it's much easier to maintain the html 21 | code, as a programmer can only take care for the application code, and a 22 | html designer can do changes to the html code without asking the programmer 23 | to change his code. 24 | 25 | 26 | 2. How do you install it? 27 | 28 | It's fairly easy. For C, do a "make" in the root directory of the archive, the 29 | resulting library (libflate.a) should be linked with your C cgi. 30 | (gcc cgi.c -o cgi -L/path/to/Flate -I/path/to/Flate -lflate) 31 | Perl support is also included, but don't bug me with it as I don't know much 32 | about perl. To install the module, change dir to perl5/CGI/TemplateHTML in the 33 | archive, then do a "perl Makefile.PL; make; make install". That should do it. 34 | If you want to use the fetch from another server feature you will have to 35 | add -D_USE_FETCH_ in the makefile and link your program with -lfetch. It 36 | requires the libfetch library as the one found in FreeBSD (I have no idea for 37 | the other operating systems!) 38 | 39 | 40 | 3. How does it work? 41 | 42 | 3.1. HTML code 43 | 44 | Your html code will now contain variables that will be easily modified by 45 | the application through the library. That is, when you design your page, you 46 | can now do it exactly how you want it to appear to the user, but the zones 47 | that the CGI can change will appear as the following: 48 | ##variable## for a text zone. 49 | for 50 | a zone that may appear or not, depending on what the CGI decides 51 | for a zone 52 | that may appear or not, multiple times (used when you draw a table for example, 53 | you can change the columns value with ##variables##). 54 | 55 | An example of a simple html template would be: 56 | 57 |

    58 | ##title## 59 |

    60 | 61 |

    62 | 63 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 74 |

    75 | The following events are recorded in your database: 76 | 77 | 78 | 79 | 82 | 85 | 86 | 87 |
    80 | ##number## 81 | 83 | ##value## 84 |
    88 | 89 | 90 | 91 | Version 1.4.1 features a new tool to check your HTML templates. Use the 92 | program "checktpl" followed by the name of your template to validate 93 | your HTML code (when the code gets complex it's easy to mispell a 94 | zone or table name: this would result in the page not being displayed 95 | correctly, or even not at all on Netscape for example if a 96 | is not closed). 97 | 98 | Since version 1.4.3 you can also include external files, called from the 99 | template with 100 | 101 | 102 | 3.2. CGI code 103 | 104 | 3.2.1. C code 105 | 106 | You first need to include "flate.h" in your program. 107 | 108 | templateSetFile("template.html"); 109 | this will load the file into memory and initialize the template. 110 | 111 | starting from version 1.4.2 there's an alternative to fetch the template 112 | from another web server: 113 | templateSetFileURL("http://myserver.com/template.html"); 114 | it will return -1 if the fetch failed 115 | 116 | templateSetVar("variable", "value"); 117 | this function will set ##variable## to "value". 118 | 119 | templateSetVar("myzone", ""); 120 | is used to display a 121 | block. If you don't call this function, the zone will not be displayed. 122 | 123 | templateDumpTableLine("dbline"); 124 | will print the zone between #BEGINTABLE and #ENDTABLE, with the variables 125 | set before. Once printed, the variables are set to NULL again, you can 126 | reuse templateSetVar("variable", "value"); to set them for the next 127 | templateDumpTableLine("dbline"); 128 | 129 | Once you're done, you can use: 130 | templatePrint(); 131 | this will output the whole page (the result) to stdout. 132 | or 133 | buf = templatePage(); (buf being a char *) 134 | this will dump the output in a buffer pointed by buf. You need to free(buf); 135 | after using this function. 136 | 137 | templateFreeMem(); 138 | will free all memory used by the template. 139 | 140 | 141 | 3.2.2. Perl code 142 | 143 | This isn't much different, TemplateHTML is part of the CGI module when 144 | installed: 145 | 146 | use CGI::TemplateHTML; 147 | 148 | my $template = new CGI::TemplateHTML(); 149 | 150 | and you can then use the methods 151 | $template->setFile("file.html"); (see templateSetFile() in C) 152 | $template->setVar("variable", "value"); (see templateSetVar()) 153 | $template->dumpTableLine("dbline"); (see templateDumpTableLine()) 154 | 155 | template->print; will show the page 156 | 157 | 158 | 4. Some notes 159 | 160 | This document won't help you realize the full potential of the library, 161 | I'm sorry about it. Just imagine that having no more html code in your C 162 | or perl code is a real enjoyment. 163 | Furthermore, you can set your variables in any order, and a change in the html 164 | code doesn't mean a change in the CGI code. 165 | The library has been used for years in production world on rather big sites 166 | like societe.com and dir.com with no crash/excessive load due to the library. 167 | That said, the C CGIs exits after serving the query, I can't be as certain for 168 | flate1.5 because I haven't tested it much, nor can I guarantee there are 169 | no memory leaks with, say, FastCGI for example. 170 | 171 | Included in the subdirectory flate1.5 is an evolution of Flate which can 172 | handle more than one object in memory, but it breaks compatibility 173 | with the older versions and does not support Perl anymore. So far I haven't 174 | had any use for this "evolution", so I don't feel like releasing it as a new 175 | version yet. Judge for yourself... 176 | 177 | Thanks to Luc Chatelain for pointing out a few problems to me, namely the 178 | void * different behaviour on SCO than in the GNU world. 179 | Thanks to Niraj Gupta for correcting issues on 1.5 with G++, fixing a free() 180 | issue and making it -Wall compliant. 181 | -------------------------------------------------------------------------------- /lib/flate-2.0.1/README.md: -------------------------------------------------------------------------------- 1 | NOTE: For a version of the FLATE Library suitable for using with the FastCGI 2 | FCGX (fcgiapp.h) API, checkout the fcgx branch. 3 | 4 | -- Andrew Clayton 5 | 6 | FLATE Library (Fast Template 2.0.1) 7 | (c) Fabien MENEMENLIS (nihilist@dead-inside.org) 8 | 9 | This program is released under the LGPL License. For copying information 10 | see the file COPYING. 11 | 12 | 13 | 1. Description 14 | 15 | FLATE is a library used to handle HTML template files outside C code as well as 16 | basic CGI input/output such as retrieving variables from HTML forms or cookies. 17 | Template files can be manipulated from the C code with various functions to 18 | change variables and display or hide part of the HTML code. The best way to 19 | sum it up would be that printf("hello"); is now history. 20 | 21 | 22 | 2. Installation 23 | 24 | Simply do a "make" in the root directory of the archive. The resulting library 25 | should be linked with your C cgi: 26 | gcc cgi.c -o cgi -L/path/to/Flate -I/path/to/Flate -lflate 27 | 28 | 29 | 3. Changes 30 | 31 | Flate 2.0 breaks compatibility with version 1.4 as it can now handle more than 32 | a template file in memory at a time. Perl support has also been removed due to 33 | my lack of interest for this language. 34 | 35 | 36 | 4. Documentation 37 | 38 | 4.1. HTML Code 39 | 40 | A few extensions have been added to the HTML language so that you can easily 41 | modify the code from your C application. 42 | ##variable## is a text zone that will be replaced by the value you want when you 43 | call flateSetVar(f, "variable", "value"); 44 | is a 45 | zone that will be hidden until you call flateSetVar(f, "myzone", ""); 46 | is a zone 47 | that will be displayed as many times as you call the function 48 | flateDumpTableLine(f, "mytable"); 49 | 50 | 51 | 4.2 Sample HTML code 52 | 53 | 54 |

    55 | ##title## 56 |

    57 | 58 |

    59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 71 |

    72 | The following events are recorded in your database: 73 |

    74 | 75 | 76 | 79 | 82 | 83 | 84 |
    77 | ##number## 78 | 80 | ##value## 81 |
    85 | 86 | 87 | 88 | 89 | You can nest tables inside tables, variables and zones inside other zones etc. 90 | 91 | You can use the tool "checktpl" to check if your HTML template is valid 92 | (when the code gets complex it's easy to mispell a zone or table name: this 93 | would result in the page not being displayed correctly, or even not at all). 94 | 95 | You can also include external template files using 96 | 97 | Note that that path is relative to the SERVER_ROOT variable set in your 98 | Apache/web server environment (this wasn't true with Flate 1.4). 99 | 100 | 101 | 4.3. Template functions 102 | 103 | You first need to include "flate.h" in your program. 104 | Each template in memory will be allocated in a Flate structure that you have 105 | to declare: 106 | Flate *f = NULL; 107 | It must be set to NULL, or the function freeing the structure will be called, 108 | leading to a crash if *f points to a random pointer. 109 | 110 | flateSetFile(&f, "template.html"); 111 | will load the file into memory and initialize the f template. 112 | 113 | flateSetVar(f, "variable", "value"); 114 | will set ##variable## in the HTML template to "value". 115 | 116 | flateSetVar(f, "myzone", ""); 117 | will display the block between 118 | 119 | 120 | flateDumpTableLine(f, "dbline"); 121 | will print the zone between #BEGINTABLE and #ENDTABLE, with the variables 122 | set before. Once printed, the variables are set to NULL again, you can 123 | reuse flateSetVar(f, "variable", "value"); to set them for the next 124 | flateDumpTableLine(f, "dbline"); 125 | 126 | Once you're done, you can use: 127 | flatePrint(f, "text/html"); 128 | this will output the whole page (the result) to stdout with the given content 129 | type. 130 | You can also populate a buffer with char *buf = flatePage(f); 131 | this will dump the output in a buffer pointed by buf. You need to free(buf); 132 | after using this function. 133 | 134 | flateFreeMem(f); 135 | will free all memory used by the f template. 136 | 137 | 138 | 4.4. Form reading 139 | 140 | Flate 2.0 can easily retrieve variables from HTML Forms passed with the GET or 141 | POST method indifferently. 142 | You must first declare a FlateForm structure: 143 | FlateForm *form = NULL; 144 | 145 | You have then two methods to pass the variables you want to retrieve: 146 | 147 | - add them one by one with the flateAddForm() function: 148 | form = firstfield = flateAddForm(form, "variable", 50, isalnum); 149 | "variable" is the variable name in the HTML Form, 50 the maximum length of 150 | the string and isalnum a function called to check the validity of the 151 | characters passed in the form, or NULL if you don't want to check the user 152 | input. 153 | You would add another variable with 154 | form = secondfield = flateAddForm(form, "second", 30, NULL); 155 | (this is a linked list so you need to point flateAddForm() to "form" every 156 | time you add a variable) 157 | 158 | - pass a single string with all the variables: 159 | char *s; 160 | s = strdup("variable,50:second,30"); 161 | form = flateSetForm(s); 162 | free(s); 163 | Note that the s string will be modified by flateSetForm() so you cannot do 164 | a simple char *s = "variable,50:second,30"; as the string declared this way 165 | is read only. 166 | 167 | Once you have set the variables you want to retrieve, call flateReadForm(form); 168 | to populate the internal buffers with the HTML form values. 169 | 170 | To access the variables values, if you have used flateAddForm() you can 171 | directly access firstfield->value for the first variable or second->value for 172 | the second: they will contain the variables passed with the GET or POST methods 173 | (as a char * type) or NULL if the form does not contain these variable names. 174 | If you have used flateSetForm() you can get the variable value with 175 | char *val = flateGetForm(form, "variable"); 176 | 177 | 178 | 4.5. Cookies manipulation 179 | 180 | Cookies manipulation is really basic but I included these functions for people 181 | like me who always forget about the format of HTTP cookies: 182 | 183 | flateSetCookie(Flate *f, char *name, char *value, char *domain, time_t expires); 184 | expires is in seconds or 0 for a session cookie or -1 to remove it 185 | cookies are set in the HTTP headers so they will be set when flatePrint() is 186 | called. 187 | 188 | flateGetCookie(char *value, int valuesz, char *cookie, check_function); 189 | will retrieve the cookie named in "cookie" inside the "value" buffer if 190 | characters matches the check_function() or NULL when no checking is wanted. 191 | Example: 192 | char cookie[50 + 1]; 193 | flateGetCookie(cookie, 50, "mycookie", isdigit); 194 | 195 | Note that flateSetCookie() is bound to a Flate structure, so you have to call 196 | flateSetFile() with a template file first. It might be a problem if you don't 197 | want to print anything after you have set a cookie and instead need to do 198 | a redirect, but I've not come accross a better API idea yet. 199 | 200 | 201 | 5. Suggestions and bug reports 202 | 203 | You can reach me at the following address: nihilist dead-inside.org if 204 | you have any question or want to report a bug. 205 | 206 | Fabien MENEMENLIS 207 | 208 | -------------------------------------------------------------------------------- /lib/cgic/cgic.h: -------------------------------------------------------------------------------- 1 | /* The CGI_C library, by Thomas Boutell, version 2.01. CGI_C is intended 2 | to be a high-quality API to simplify CGI programming tasks. */ 3 | 4 | /* Make sure this is only included once. */ 5 | 6 | #ifndef CGI_C 7 | #define CGI_C 1 8 | 9 | /* Bring in standard I/O since some of the functions refer to 10 | types defined by it, such as FILE *. */ 11 | 12 | #include 13 | 14 | /* The various CGI environment variables. Instead of using getenv(), 15 | the programmer should refer to these, which are always 16 | valid null-terminated strings (they may be empty, but they 17 | will never be null). If these variables are used instead 18 | of calling getenv(), then it will be possible to save 19 | and restore CGI environments, which is highly convenient 20 | for debugging. */ 21 | 22 | extern char *cgiServerSoftware; 23 | extern char *cgiServerName; 24 | extern char *cgiGatewayInterface; 25 | extern char *cgiServerProtocol; 26 | extern char *cgiServerPort; 27 | extern char *cgiRequestMethod; 28 | extern char *cgiPathInfo; 29 | extern char *cgiPathTranslated; 30 | extern char *cgiScriptName; 31 | extern char *cgiQueryString; 32 | extern char *cgiRemoteHost; 33 | extern char *cgiRemoteAddr; 34 | extern char *cgiAuthType; 35 | extern char *cgiRemoteUser; 36 | extern char *cgiRemoteIdent; 37 | extern char *cgiContentType; 38 | extern char *cgiAccept; 39 | extern char *cgiUserAgent; 40 | extern char *cgiReferrer; 41 | 42 | /* Cookies as sent to the server. You can also get them 43 | individually, or as a string array; see the documentation. */ 44 | extern char *cgiCookie; 45 | 46 | /* A macro providing the same incorrect spelling that is 47 | found in the HTTP/CGI specifications */ 48 | #define cgiReferer cgiReferrer 49 | 50 | /* The number of bytes of data received. 51 | Note that if the submission is a form submission 52 | the library will read and parse all the information 53 | directly from cgiIn; the programmer need not do so. */ 54 | 55 | extern int cgiContentLength; 56 | 57 | /* Pointer to CGI output. The cgiHeader functions should be used 58 | first to output the mime headers; the output HTML 59 | page, GIF image or other web document should then be written 60 | to cgiOut by the programmer. In the standard CGIC library, 61 | cgiOut is always equivalent to stdout. */ 62 | 63 | extern FILE *cgiOut; 64 | 65 | /* Pointer to CGI input. The programmer does not read from this. 66 | We have continued to export it for backwards compatibility 67 | so that cgic 1.x applications link properly. */ 68 | 69 | extern FILE *cgiIn; 70 | 71 | /* Possible return codes from the cgiForm family of functions (see below). */ 72 | 73 | typedef enum { 74 | cgiFormSuccess, 75 | cgiFormTruncated, 76 | cgiFormBadType, 77 | cgiFormEmpty, 78 | cgiFormNotFound, 79 | cgiFormConstrained, 80 | cgiFormNoSuchChoice, 81 | cgiFormMemory, 82 | cgiFormNoFileName, 83 | cgiFormNoContentType, 84 | cgiFormNotAFile, 85 | cgiFormOpenFailed, 86 | cgiFormIO, 87 | cgiFormEOF 88 | } cgiFormResultType; 89 | 90 | /* These functions are used to retrieve form data. See 91 | cgic.html for documentation. */ 92 | 93 | extern cgiFormResultType cgiFormString( 94 | char *name, char *result, int max); 95 | 96 | extern cgiFormResultType cgiFormStringNoNewlines( 97 | char *name, char *result, int max); 98 | 99 | 100 | extern cgiFormResultType cgiFormStringSpaceNeeded( 101 | char *name, int *length); 102 | 103 | 104 | extern cgiFormResultType cgiFormStringMultiple( 105 | char *name, char ***ptrToStringArray); 106 | 107 | extern void cgiStringArrayFree(char **stringArray); 108 | 109 | extern cgiFormResultType cgiFormInteger( 110 | char *name, int *result, int defaultV); 111 | 112 | extern cgiFormResultType cgiFormIntegerBounded( 113 | char *name, int *result, int min, int max, int defaultV); 114 | 115 | extern cgiFormResultType cgiFormDouble( 116 | char *name, double *result, double defaultV); 117 | 118 | extern cgiFormResultType cgiFormDoubleBounded( 119 | char *name, double *result, double min, double max, double defaultV); 120 | 121 | extern cgiFormResultType cgiFormSelectSingle( 122 | char *name, char **choicesText, int choicesTotal, 123 | int *result, int defaultV); 124 | 125 | 126 | extern cgiFormResultType cgiFormSelectMultiple( 127 | char *name, char **choicesText, int choicesTotal, 128 | int *result, int *invalid); 129 | 130 | /* Just an alias; users have asked for this */ 131 | #define cgiFormSubmitClicked cgiFormCheckboxSingle 132 | 133 | extern cgiFormResultType cgiFormCheckboxSingle( 134 | char *name); 135 | 136 | extern cgiFormResultType cgiFormCheckboxMultiple( 137 | char *name, char **valuesText, int valuesTotal, 138 | int *result, int *invalid); 139 | 140 | extern cgiFormResultType cgiFormRadio( 141 | char *name, char **valuesText, int valuesTotal, 142 | int *result, int defaultV); 143 | 144 | /* The paths returned by this function are the original names of files 145 | as reported by the uploading web browser and shoult NOT be 146 | blindly assumed to be "safe" names for server-side use! */ 147 | extern cgiFormResultType cgiFormFileName( 148 | char *name, char *result, int max); 149 | 150 | /* The content type of the uploaded file, as reported by the browser. 151 | It should NOT be assumed that browsers will never falsify 152 | such information. */ 153 | extern cgiFormResultType cgiFormFileContentType( 154 | char *name, char *result, int max); 155 | 156 | extern cgiFormResultType cgiFormFileSize( 157 | char *name, int *sizeP); 158 | 159 | typedef struct cgiFileStruct *cgiFilePtr; 160 | 161 | extern cgiFormResultType cgiFormFileOpen( 162 | char *name, cgiFilePtr *cfpp); 163 | 164 | extern cgiFormResultType cgiFormFileRead( 165 | cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP); 166 | 167 | extern cgiFormResultType cgiFormFileClose( 168 | cgiFilePtr cfp); 169 | 170 | extern cgiFormResultType cgiCookieString( 171 | char *name, char *result, int max); 172 | 173 | extern cgiFormResultType cgiCookieInteger( 174 | char *name, int *result, int defaultV); 175 | 176 | cgiFormResultType cgiCookies( 177 | char ***ptrToStringArray); 178 | 179 | /* path can be null or empty in which case a path of / (entire site) is set. 180 | domain can be a single web site; if it is an entire domain, such as 181 | 'boutell.com', it should begin with a dot: '.boutell.com' */ 182 | extern void cgiHeaderCookieSetString(char *name, char *value, 183 | int secondsToLive, char *path, char *domain); 184 | extern void cgiHeaderCookieSetInteger(char *name, int value, 185 | int secondsToLive, char *path, char *domain); 186 | extern void cgiHeaderLocation(char *redirectUrl); 187 | extern void cgiHeaderStatus(int status, char *statusMessage); 188 | extern void cgiHeaderContentType(char *mimeType); 189 | 190 | typedef enum { 191 | cgiEnvironmentIO, 192 | cgiEnvironmentMemory, 193 | cgiEnvironmentSuccess, 194 | cgiEnvironmentWrongVersion 195 | } cgiEnvironmentResultType; 196 | 197 | extern cgiEnvironmentResultType cgiWriteEnvironment(char *filename); 198 | extern cgiEnvironmentResultType cgiReadEnvironment(char *filename); 199 | 200 | extern int cgiMain(); 201 | 202 | extern cgiFormResultType cgiFormEntries( 203 | char ***ptrToStringArray); 204 | 205 | /* Output string with the <, &, and > characters HTML-escaped. 206 | 's' is null-terminated. Returns cgiFormIO in the event 207 | of error, cgiFormSuccess otherwise. */ 208 | cgiFormResultType cgiHtmlEscape(char *s); 209 | 210 | /* Output data with the <, &, and > characters HTML-escaped. 211 | 'data' is not null-terminated; 'len' is the number of 212 | bytes in 'data'. Returns cgiFormIO in the event 213 | of error, cgiFormSuccess otherwise. */ 214 | cgiFormResultType cgiHtmlEscapeData(char *data, int len); 215 | 216 | /* Output string with the " character HTML-escaped, and no 217 | other characters escaped. This is useful when outputting 218 | the contents of a tag attribute such as 'href' or 'src'. 219 | 's' is null-terminated. Returns cgiFormIO in the event 220 | of error, cgiFormSuccess otherwise. */ 221 | cgiFormResultType cgiValueEscape(char *s); 222 | 223 | /* Output data with the " character HTML-escaped, and no 224 | other characters escaped. This is useful when outputting 225 | the contents of a tag attribute such as 'href' or 'src'. 226 | 'data' is not null-terminated; 'len' is the number of 227 | bytes in 'data'. Returns cgiFormIO in the event 228 | of error, cgiFormSuccess otherwise. */ 229 | cgiFormResultType cgiValueEscapeData(char *data, int len); 230 | 231 | #endif /* CGI_C */ 232 | 233 | -------------------------------------------------------------------------------- /Doc/Develop_Notes.md: -------------------------------------------------------------------------------- 1 | # Embedded-GUI-Develop 2 | 嵌入式LINUX 的 Web-GUI 在LINUX主机上开发(CGI)--使用mini-httpd,便于编译和可以直接移植。 3 | 4 | > 本文档将最新内容放在上部。按日期从早期到现在对应内容为自下向上。 5 | 6 | 7 | 8 | **注:推荐本地使用 Typora 打开 README.md** 9 | 10 | 11 | 12 | *Overview* 13 | 14 | [TOC] 15 | 16 | ## Contents 17 | 18 | **master** 19 | 20 | ``` 21 | ------------- README.md ----------- 22 | Embedded-GUI-Develop 23 | Contents 24 | Summary 25 | ToDo 26 | ChangeLog 27 | Aug/06/2018 28 | Aug/05/2018 29 | Aug/04/2018 30 | 2018/Jul/22 31 | 2018/Jul/21 32 | daemonEcho2 33 | 2018/Jul/09 34 | 2018/Jul/08 35 | 2018/Jul/07 36 | 2018/Jul/03 -- mini_httpd 37 | 2018/Jul/01 -- CGIDebugLog 38 | Note 39 | ``` 40 | 41 | 42 | 43 | ## summary 44 | 45 | 编译和运行总览: 46 | 47 | ```shell 48 | $ make init 49 | $ make LIB 50 | $ make BIN 51 | $ make Include 52 | $ 53 | $ sudo make install #### 安装 python 程序所需的库。 54 | $ 55 | $ cp bin/* WorkPath/bin/ 56 | $ 57 | $ ###### 运行环境 ###### 58 | $ #### 1. 运行 mini_httpd ###### 59 | $ ## a. 需要修改 mini_httpd.conf 文件 60 | $ ## b. 运行 mini_httpd 命令 61 | $ ## a. & b. 查看 "2018/Jul/22 -> usage" 一节 62 | $ 63 | $ #### 2. 运行 CGIDebugLogd.py 在后台 64 | $ cd WorkPath/ && ./bin/DaemonEcho2 start `tty` && cd ../ 65 | $ 66 | $ ## 切换 输出终端方式: 67 | $ cd WorkPath/ && ./bin/DaemonEcho2 restart && cd ../ 68 | $ ## should like: /dev/ttyS0 or /dev/pts/1 etc.. 69 | $ 70 | $ ## 运行测试 71 | $ ## 分为 *.c 的 src/ 和 *.html 的 html/ 72 | $ ## 分别修改 src/Makefile 和 html/Makefile 73 | $ make SRC ## or $ make --directory=src 74 | $ make --directory=src install 75 | $ 76 | $ make html ## or $ make --directory=html 77 | $ make --directory=html install 78 | $ 79 | ``` 80 | 81 | 82 | 83 | ## ToDo 84 | 85 | - [x] 通过打 patch 的方式修改,而非在 source code 里面修改,或者Makefile;daemonEcho2.c 和 htpasswd.c 86 | 87 | 2018/Jul/03 build_patch.py fix htpasswd.c build. 88 | 89 | - [x] CGIDebugLogd 使用 python-daemon solution 90 | - [x] flate API 向下兼容 91 | - [x] README.md 的 `$ make Include` 说明! 92 | - [ ] make install 的 python install 和 *.cgi; *.html install 区分。 93 | 94 | 95 | 96 | ## **Note** 97 | 98 | ​ N/A 99 | 100 | 101 | 102 | ## Change Log 103 | 104 | ### Aug/07/2018 105 | 106 | 1. 确认需要使用 flate-2.0.1 107 | 108 | flate-2.0.1 API 兼容在 109 | 110 | 2. 添加 build-deps.txt 111 | 112 | 113 | 114 | ### Aug/06/2018 115 | 116 | 1. update Makefile 117 | 118 | set MOVE instead of COPY; 119 | 120 | save Makefile as UTF-8 encode. 121 | 122 | 2. merge ***easy_GUI_develop/github_Embedded-GUI-Develop*** develop revision to *Branch/br-github_EbdGUIDevelop/*. 123 | 124 | 3. prepare for flate-1.4.6 125 | 126 | 4. update README.md for `$ make Include` ; (and **Jul/22** more detail.) 127 | 128 | 5. test flate-1.4.6 -than-> -[x]update 本 REAME.md 129 | 130 | 从 MTK 的 OBM trunk 上找到了原版的 flate-1.4.6 和 flate-1.5.6. 131 | 132 | 其中,flate-1.5.6 和 flate-2.0.1 接近,改动较大,不向下兼容,所以不使用。 133 | 134 | 135 | ​ 136 | 137 | 138 | 139 | ### Aug/05/2018 140 | 141 | **fixed** CGIDebugLogd 使用 python-daemon solution 142 | 143 | 使用 python-daemon 同时 **fixed** 重新分配 tty 的问题! 144 | 145 | 146 | 1. 因为 python-daemon 库在 WorkPath/lib/python3.5/ 中, 所以启动 DaemonEcho2 **必须严格** 路径! 147 | 2. 启动 DaemonEcho2 命令: `WorkPath/ $ ./bin/DaemonEcho2 start ` (如: ./bin/DaemonEcho2 "/dev/pts/1" ) 148 | 3. **python-daemon 库的 runner.py 有bug, 做了 fix 在上述路径中!** 149 | 4. 重新分配 tty 命令(Example): `WorkPath/ $ ./bin/DaemonEcho2 restart "/dev/ttyS0"` 150 | 151 | 152 | 153 | ### Aug/04/2018 154 | 155 | 1. update README.md 156 | 157 | 2. README.md 使用新结构 -- Contents, Summary, ToDo, Note, ChangeLog. 158 | 159 | 添加 ToDo 内容。(内容 SYNC [GitHub 上的 Issue -> ToDo](https://github.com/RDpWTeHM/Embedded-GUI-Develop/issues/1)) 160 | 161 | 162 | 163 | ### 2018/Jul/22 164 | 165 | 1. 添加 mini_httpd.conf 的自动适应环境patch! 166 | 2. CGIDebugLogc.* 的 API 封装 167 | 3. Makefile 的 `$ make Include` 168 | 4. build *hello-CGIDebugLog.c* with *libCGIDebugLogc.a* new API 169 | 170 | 171 | 172 | #### Detail: 173 | 174 | *1. mini_httpd.conf patch* 175 | 176 | ​ 使用了 jinja2 库,通过模板修改 mini_httpd.conf.jinja2 并创建一个新文件 mini_httpd.conf,将修改得到的数据输出到 minni_httpd.conf 文件中。 177 | 178 | ​ 使用 jinja2 库: 179 | 180 | ```shell 181 | $ python3 -c "import jinja2" ## 测试主机环境中是否有 jinja2 库 182 | $ 183 | $ sudo apt-get install python3-pip ## 如果还未安装过 pip 的话执行这条命令。 184 | $ 185 | $ sudo pip3 install --upgrade jinja2 ## 安装 jinja2 库。 186 | $ 187 | ``` 188 | 189 | #### *usage* 190 | 191 | a. 修改 mini_httpd.conf 文件使适应主机运行环境。 192 | 193 | 方式一, 使用 mini_httpd.patch: 194 | 195 | ```shell 196 | $ ## 按上述 Detail -> 使用 jinja2 库, 安装 jinja2 库。 197 | $ ./WorkPath/etc/mini_httpd/mini_httpd.patch 198 | $ 199 | ``` 200 | 201 | 方式二, 手动修改: 202 | 203 | ```shell 204 | $ cp ./WorkPath/etc/mini_httpd/mini_httpd.conf.Reference ./WorkPath/etc/mini_httpd/mini_httpd.conf 205 | $ ## 修改 mini_httpd.conf 中的路径。 206 | ``` 207 | 208 | b. 运行 mini_httpd 209 | 210 | ```shell 211 | $ ./WorkPath/bin/mini_httpd -C ./WorkPath/etc/mini_httpd/mini_httpd.conf 212 | ``` 213 | 214 | 215 | 216 | 2. N/A 217 | 218 | 219 | 3. Makefile; include/Makefile 220 | -- 创建 *.h 文件的软链接 for build. 221 | 222 | 4. build hello-CGIDebugLog.c: 223 | 224 | `$ gcc -I ../include hello-CGIDebugLog.c ../lib/libCGIDebugLogc.a -o hello-CGIDebugLog.cgi` 225 | 226 | ​ 227 | 228 | ### 2018/Jul/21 229 | 230 | merge 了 Jul-19-ToDo 这个branch 的 develop, 231 | 232 | 1. 添加了 CGIC 库 233 | 2. 添加了 Flate 库 234 | 3. daemonEcho2 进程的相关启动做了修改。 235 | 236 | ### daemonEcho2 237 | 238 | **启动方式:** 239 | 240 | ```shell 241 | $ ## 运行过 $ cp bin/* WorkPath/bin* 命令之后, 242 | $ ## 启动方式1: 243 | $ ./WorkPath/bin/daemonEcho2 `tty` 244 | $ 245 | $ ## 或者不copy bin/ 目录下的 daemonEcho2 程序; 246 | $ ## 或者将 daemonEcho2 程序拷贝到其它位置 247 | $ ## 启动方式2: 248 | $ /daemonEcho2 `tty` /CGIDebugLogd.py 249 | $ 250 | ``` 251 | 252 | **daemonEcho2 程序说明:** 253 | 254 | ​ daemonEcho2 至少需要指定输出的终端名,可以使用 `$ tty` 命令查看当前的终端名。 255 | 256 | ​ 默认情况下(只指定输出终端), daemonEcho2 将假设 CGIDebugLogd.py 所在路径和它同级,然后打开 CGIDebugLogd.py 进程,将其 daemon 化,并且退出自身这个进程。 257 | 258 | ​ 以上述 “启动方式2” 启动,daemonEcho2 将去指定位置运行 CGIDebugLogd.py 进程。 259 | 260 | 261 | 262 | ### 2018/Jul/09 263 | 264 | #### *.cgi 使用 libCGIDebugLogc.a 测试 265 | 266 | 测试文件为: `src/hello-CGIDebugLog.c` , 267 | 268 | 编译出 *.cgi: 269 | 270 | `src/ $ gcc hello-CGIDebugLog.c ../lib/libCGIDebugLogc.a -o hello-CGIDebugLog.cgi` 271 | 272 | 手动安装:`/ $ mv ./src/hello-CGIDebugLog.cgi ./WorkPath/var/www/cgi-bin/` 273 | 274 | 打开浏览器测试(在mini_httpd 和 CGIDebugLogd.py 正常运行的情况下)。 275 | 276 | 277 | 278 | ### 2018/Jul/08 279 | 280 | #### 新增 CGIDebugLogc 测试 281 | 282 | 1. 确保 *2018/Jul/08 -> CGIDebugLogd 运行* 一节中的 CGIDebugLogd.py 在后台运行。 283 | 284 | 2. 编译出 CGIDebugLogc 的测试用例: 285 | 286 | ```shell 287 | $ cd libraries/DebugLog_solution/src/CGIDebugLogc/ 288 | $ make 289 | $ ## ^ 编译出 libCGIDebugLogc.a 290 | $ 291 | $ make tester 292 | ``` 293 | 294 | 3. 运行测试用例: 295 | 296 | ```shell 297 | $ pwd 298 | /Embedded-GUI-Develop/libraries/DebugLog_solution/src/CGIDebugLogc/ 299 | $ ## 在 2. 的路径基础上。 300 | $ ./tester ## 可以通过其它终端运行(路径要和上面pwd一样) 301 | $ ## 可以在运行 CGIDebugLogd.py 打开的终端中看到输出! 302 | ``` 303 | 304 | ### CGIDebugLogd 运行 305 | 306 | 更新过了 daemonEcho2.c 为了适合 WorkPath/ 目录结构 307 | 308 | 使 CGIDebugLogd.py 正常运行的命令: 309 | 310 | ```shell 311 | $ cp ./libraries/daemonEcho2 ./WorkPath/bin/ 312 | $ cp ./libraries/CGIDebugLogd.py ./WorkPath/bin/ 313 | $ 314 | $ cd WorkPath 315 | $ ./bin/daemonEcho2 `tty` 316 | ``` 317 | 318 | 319 | 320 | ### 2018/Jul/07 321 | 322 | #### mini_httpd + CGI 运行测试 323 | 324 | > 添加 HTML-hello.c -> HTML-hello.cgi 测试 Web server 环境 325 | 326 | .../src/ $ gcc HTML-hello.c -o HTML-hello.cgi 327 | .../src/ $ cp HTML-hello.cgi ../WorkPath/var/www/cgi-bin/ 328 | 329 | 使用浏览器 http://localhost:8282/cgi-bin/HTML-hello.cgi 运行测试 330 | 331 | 332 | 333 | #### mini_httpd.conf 配置文件--mini_httpd运行环境 334 | 335 | 查看 WorkPath/README.md 336 | 337 | 338 | 339 | #### 避免重复编译 340 | 341 | 基本使用: 342 | 343 | ```shell 344 | $ ## root 路径 345 | $ make init 346 | $ make lib 347 | $ make 348 | $ 349 | ``` 350 | 351 | 依赖库(CGIDebugLog,mini_httpd)在文件夹下,因为文件夹时间戳和文件的时间戳有些不同,所以看起来应该需要一些妥协方案。 352 | 353 | 354 | 355 | ### 2018/Jul/03 -- mini_httpd 356 | 357 | ```shell 358 | $ cd libraries 359 | $ make 360 | $ ls -lF 361 | mini_httpd* 362 | CGIDebugLogd.py 363 | daemonEcho2* 364 | ... 365 | ``` 366 | 367 | 368 | 369 | ### 2018/Jul/01 -- CGIDebugLog 370 | 371 | ```shell 372 | $ 373 | $ make lib 374 | $ sudo make install 375 | $ 376 | $ ./libraries/daemonEcho2 `tty` 377 | $ 378 | $ ps aux | grep python 379 | $ 380 | ``` 381 | 382 | CGIDebugLog automatic finished! 383 | 384 | 385 | --------------------------------------------------------------------------------