From be84c3ce8e106905a25c960aeb1ae3aa91317827 Mon Sep 17 00:00:00 2001 From: pans <pans@454eff88-639b-444f-9e54-f578c98de674> Date: 星期一, 09 一月 2017 16:11:52 +0800 Subject: [PATCH] --- Lighttpd/mycgi/mycgi.cpp | 29 + Lighttpd/mycgi/ccgi.cpp | 255 +++++++++++++++++ Lighttpd/conf.back/lighttpd.conf | 39 ++ Lighttpd/conf.back/ctrlc.cpp | 431 ++++++++++++++++++++++++++++ Lighttpd/conf.back/fastcgi.conf | 113 +++++++ 5 files changed, 867 insertions(+), 0 deletions(-) diff --git a/Lighttpd/conf.back/ctrlc.cpp b/Lighttpd/conf.back/ctrlc.cpp new file mode 100644 index 0000000..41d10c8 --- /dev/null +++ b/Lighttpd/conf.back/ctrlc.cpp @@ -0,0 +1,431 @@ +#ifndef nullptr +#define nullptr NULL +#endif + +#include <unistd.h> +#include <time.h> +#include <errno.h> + +#include <stdlib.h> +#include <iostream> +#include <map> +#include <vector> +#include <string> +#include <sstream> +#include <algorithm> +#include <iterator> +#include <cctype> + +using namespace std; + +// http://www.fastcgi.com +#include <fcgi_stdio.h> +#include <fcgi_config.h> + +// http://uriparser.sourceforge.net +#include <uriparser/Uri.h> + +// http://www.postgresql.org +//#include <pgsql/libpq-fe.h> +#include <libpq-fe.h> + +// https://github.com/open-source-parsers/jsoncpp +#include <json/json.h> + +#define SOCK_TCP +#include <cmdhub/client.h> + +#include "sqlmaker/sqlmaker.h" + +my_id_t get_my_id() +{ + static my_id_t myid = 0; + myid++; + return myid; +} + +char to_upper(char c) +{ + return toupper((int)c); +} + +extern char **environ; +static char **g_initial_nv = nullptr; +static size_t g_req_count = 0; + +stringstream g_log_msg; +stringstream g_http_res; + +typedef void (*url_process_func_t)(); +typedef map<string, url_process_func_t> upf_map_t; +static upf_map_t g_url_processors; + +typedef map<string, string> str_map_t; + +static void http_res_200(const char* msg) +{ + FCGI_printf("Status: 20 OK\r\n" "Content-type: text/html\r\n" "\r\n" "%s", msg); +} +static void http_res_400() +{ + FCGI_printf("Status: 400 Bad Request\r\n" "Content-type: text/html\r\n" "\r\n"); +} +static void http_res_401() +{ + FCGI_printf("Status: 401 Unauthorized\r\n" "Content-type: text/html\r\n" "\r\n"); +} +static void http_res_404() +{ + FCGI_printf("Status: 404 Not Found\r\n" "\r\n"); +} +static void http_res_500() +{ + FCGI_printf("Status: 500 Internal Server Error\r\n" "\r\n"); +} +static void http_res_500(int problem_code = 0) +{ + FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Problem code = %d", problem_code); +} +static void http_res_500(const char* msg) +{ + FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Message = %s", msg); +} + +size_t read_shell(const char* cmd, char* buffer, size_t buffer_size, int* exit_status = nullptr, int* exit_code = nullptr) +{ + if (cmd == nullptr) + return 0; + + FCGI_FILE* fcmd = FCGI_popen(cmd, "r"); + if (fcmd == nullptr) + return 0; + + size_t red = FCGI_fread(buffer, sizeof(char), buffer_size - 1, fcmd); + + int es = FCGI_pclose(fcmd); + + if (exit_status != nullptr) + *exit_status = es; + if (exit_code != nullptr) + *exit_code = WEXITSTATUS(es); + + return red; +} + +void run_in_bash(const char* cmd, int* exit_status = nullptr, int* exit_code = nullptr) +{ +#define BASH_WRAPPER "su -s /bin/bash -c '%s' http" + + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, BASH_WRAPPER, cmd); + + int es = system(buffer); + + if (exit_status != nullptr) + *exit_status = es; + if (exit_code != nullptr) + *exit_code = WEXITSTATUS(es); +} + +static void print_env(const char *label, char **envp) +{ + FCGI_printf("%s:<br>\n<pre>\n", label); + for ( ; *envp != NULL; envp++) + { + FCGI_printf("%s\n", *envp); + } + FCGI_printf("</pre><p>\n"); +} + +static void hpf_echo() +{ + g_log_msg.flush(); + + char *contentLength = getenv("CONTENT_LENGTH"); + int len; + + FCGI_printf("Content-type: text/html\r\n" + "\r\n" + "<title>FastCGI echo</title>" + "<h1>FastCGI echo</h1>\n" + "Request number %d, Process ID: %d<p>\n", g_req_count, getpid()); + + if (contentLength != NULL) + len = strtol(contentLength, NULL, 10); + else + len = 0; + + if (len <= 0) + { + FCGI_printf("No data from standard input.<p>\n"); + } + else + { + int i, ch; + + FCGI_printf("Standard input:<br>\n<pre>\n"); + for (i = 0; i < len; i++) + { + if ((ch = getchar()) < 0) + { + FCGI_printf("Error: Not enough bytes received on standard input<p>\n"); + break; + } + putchar(ch); + } + FCGI_printf("\n</pre><p>\n"); + } + + print_env("Request environment", environ); + print_env("Initial environment", g_initial_nv); +} + +bool parse_query_items(str_map_t& query_items) +{ + char* req_REQUEST_URI; + req_REQUEST_URI = getenv("REQUEST_URI"); + if (req_REQUEST_URI == nullptr) + { + g_log_msg << "can not get REQUEST_URI" << endl; + goto error_ret; + } + + char* req_QUERY_STRING; + req_QUERY_STRING = getenv("QUERY_STRING"); + if (req_QUERY_STRING == nullptr) + { + g_log_msg << "can not get QUERY_STRING" << endl; + goto error_ret; + } + else if (req_QUERY_STRING[0] == '\0') + { + g_log_msg << "QUERY_STRING is empty" << endl; + return true; + } + + UriParserStateA state; + UriUriA uri; + + state.uri = &uri; + if (uriParseUriA(&state, req_REQUEST_URI) != URI_SUCCESS) + { + g_log_msg << "uriParseUriA not success" << endl; + goto error_ret_uri_1; + } + + UriQueryListA * query_list; + query_list = nullptr; + int ql_item_count; + ql_item_count = 0; + if (uriDissectQueryMallocA(&query_list, &ql_item_count, uri.query.first, uri.query.afterLast) != URI_SUCCESS) + { + g_log_msg << "uriDissectQueryMallocA not success" << endl; + goto error_ret_uri_2; + } + + //debug: + //FCGI_printf("Content-type: text/json\r\n" "\r\n"); + + UriQueryListA* iter_query_list; + iter_query_list = query_list; + while (iter_query_list != nullptr) + { + const char* qi_key = iter_query_list->key; + const char* qi_value = iter_query_list->value; + + if(qi_key == nullptr || qi_value == nullptr) + { + g_log_msg << "query_list contains null key or value" << endl; + goto error_ret_uri_2; + } + + query_items[string(qi_key)] = string(qi_value); + //debug: + //FCGI_printf("%s=%s\n", qi_key, qi_value); + iter_query_list = iter_query_list->next; + } + + uriFreeQueryListA(query_list); + uriFreeUriMembersA(&uri); + return true; + +error_ret_uri_2: + uriFreeQueryListA(query_list); +error_ret_uri_1: + uriFreeUriMembersA(&uri); +error_ret: + return false; +} + +size_t get_post_content(char* buffer, size_t max_size, size_t offset_content = 0) +{ + if (buffer == NULL || max_size == 0) + return 0; + + const char* contentLength = getenv("CONTENT_LENGTH"); + size_t len = 0; + if (contentLength != NULL) + len = strtol(contentLength, NULL, 10); + + if (len == 0) + return 0; + + if (offset_content > 0) + fseek(stdin, offset_content, SEEK_SET); + + return fread(buffer, sizeof(char), min(max_size, len), stdin); +} + +const string* try_get_str_from_map(const str_map_t& str_map, const string& key, const string* default_value = nullptr) +{ + str_map_t::const_iterator iter = str_map.find(key); + if (iter == str_map.end()) + return default_value; + else + return &(iter->second); +} + + + + + +static void hpf_fishbowl_fish_count() +{ + g_log_msg.flush(); + + str_map_t query_items; + if (! parse_query_items(query_items)) + { + http_res_500(g_log_msg.str().c_str()); + return; + } + + Json::Value json_root; + + bool json_ret = true; + const string* qi_cmd = try_get_str_from_map(query_items, string("cmd")); + if (qi_cmd == nullptr) + { + json_root["msg"] = "cmd not needed"; + } + else + { + if (strcmp("list", qi_cmd->c_str()) == 0) + { + json_ret = hpf_fishbowl_fish_count_list(query_items, json_root); + } + else if (strcmp("variate", qi_cmd->c_str()) == 0) + { + json_ret = hpf_fishbowl_fish_count_variate(query_items, json_root); + } + else if (strcmp("summed", qi_cmd->c_str()) == 0) + { + json_ret = hpf_fishbowl_fish_count_summed(query_items, json_root); + } + else if (strcmp("graph", qi_cmd->c_str()) == 0) + { + } + else + { + json_root["msg"] = "cmd not supported"; + } + } + + if (json_ret) + { + printf("Content-type: application/json\r\n" "\r\n"); + printf("%s", json_root.toStyledString().c_str()); + } +} + +static void hpf_fishbowl_load_v4l2grab() +{ + g_log_msg.flush(); + errno = 0; + bool ret = false; + int exit_code = 0; + const std::string cmd("exec/LOAD_V4L2GRAB"); + std::string result; + + CmdhubClientSession session; + session.recv_retry = 20; + if (ret = cmdhub_client_init(session)) + { + if (ret = cmdhub_client_connect(session)) + { + ret = cmdhub_client_command(session, cmd, result, exit_code); + cmdhub_client_destory(session); + } + } + + Json::Value json_root; + json_root["return"] = ret; + if (ret) + { + json_root["exitcode"] = exit_code; + json_root["result"] = result; + } + else + { + json_root["errno"] = errno; + } + + printf("Content-type: application/json\r\n" "\r\n"); + printf("%s", json_root.toStyledString().c_str()); +} + +int main () +{ + g_initial_nv = environ; + + g_url_processors["/echo"] = hpf_echo; + g_url_processors["/fishbowl-basic-data"] = hpf_fishbowl_basic_data; + g_url_processors["/fishbowl-bdtype"] = hpf_fishbowl_bdtype; + g_url_processors["/fishbowl-fish-count"] = hpf_fishbowl_fish_count; + g_url_processors["/fishbowl-fish-type"] = hpf_fishbowl_fish_type; + g_url_processors["/fishbowl-fish-diary"] = hpf_fishbowl_fish_diary; + g_url_processors["/fishbowl-load-v4l2grab"] = hpf_fishbowl_load_v4l2grab; + //g_url_processors["/fishbowl-reminder"] = hpf_fishbowl_reminder; + + if(psql_conn() == nullptr) + { + cerr << g_log_msg.rdbuf(); + exit(EXIT_FAILURE); + } + + cerr << "begin accept access" << endl; + + int fcgi_accept_status; + + while ((fcgi_accept_status = FCGI_Accept()) >= 0) + { + g_req_count++; + g_log_msg.flush(); + + char* req_PATH_INFO = getenv("PATH_INFO"); + if(req_PATH_INFO == nullptr) + { + cerr << "PATH_INFO is null" << endl; + exit(EXIT_FAILURE); + } + + upf_map_t::iterator iter_upf = g_url_processors.find(req_PATH_INFO); + if (iter_upf == g_url_processors.end()) + { + http_res_404(); + } + else + { + url_process_func_t proc = iter_upf->second; + proc(); + } + } + + PGconn* conn = psql_conn(); + if (conn != nullptr) + PQfinish(conn); + + cerr << "exit gracefully, fcgi_accept_status=" << fcgi_accept_status << endl; + + return 0; +} diff --git a/Lighttpd/conf.back/fastcgi.conf b/Lighttpd/conf.back/fastcgi.conf new file mode 100644 index 0000000..f3e7502 --- /dev/null +++ b/Lighttpd/conf.back/fastcgi.conf @@ -0,0 +1,113 @@ +####################################################################### +## +## FastCGI Module +## --------------- +## +## See http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI +## +server.modules += ( "mod_fastcgi" ) + +## +## PHP Example +## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini. +## +## The number of php processes you will get can be easily calculated: +## +## num-procs = max-procs * ( 1 + PHP_FCGI_CHILDREN ) +## +## for the php-num-procs example it means you will get 17*5 = 85 php +## processes. you always should need this high number for your very +## busy sites. And if you have a lot of RAM. :) +## +fastcgi.server = ( +#diy + "/mycgi" => + ( + "bin-path" => "/opt/httpd/mycgi", + "check-local" => "disable", + "socket" => "/tmp/mycgi.socket" + ) + ) + +## +## Ruby on Rails Example +## +## Normally you only run one Rails application on one vhost. +## +#$HTTP["host"] == "rails1.example.com" { +# server.document-root = server_root + "/rails/someapp/public" +# server.error-handler-404 = "/dispatch.fcgi" +# fastcgi.server = ( ".fcgi" => +# ("someapp" => +# ( "socket" => socket_dir + "/someapp-fcgi.socket", +# "bin-path" => server_root + "/rails/someapp/public/dispatch.fcgi", +# "bin-environment" => ( +# "RAILS_ENV" => "production", +# "TMP" => home_dir + "/rails/someapp", +# ), +# ) +# ) +# ) +#} + +## +## Another example with multiple rails applications on one vhost. +## +## http://blog.lighttpd.net/articles/2005/11/23/lighttpd-1-4-8-and-multiple-rails-apps +## +#$HTTP["host"] == "rails2.example.com" { +# $HTTP["url"] =~ "^/someapp1" { +# server.document-root = server_root + "/rails/someapp1/public" +# server.error-handler-404 = "/dispatch.fcgi" +# fastcgi.server = ( ".fcgi" => +# ("someapp1" => +# ( "socket" => socket_dir + "/someapp1-fcgi.socket", +# "bin-path" => server_root + "/rails/someapp1/public/dispatch.fcgi", +# "bin-environment" => ( +# "RAILS_ENV" => "production", +# "TMP" => home_dir + "/rails/someapp1", +# ), +# "strip-request-uri" => "/someapp1/" +# ) +# ) +# ) +# } +# +# $HTTP["url"] =~ "^/someapp2" { +# server.document-root = server_root + "/rails/someapp2/public" +# server.error-handler-404 = "/dispatch.fcgi" +# fastcgi.server = ( ".fcgi" => +# ("someapp2" => +# ( "socket" => socket_dir + "/someapp2-fcgi.socket", +# "bin-path" => server_root + "/rails/someapp2/public/dispatch.fcgi", +# "bin-environment" => ( +# "RAILS_ENV" => "production", +# "TMP" => home_dir + "/rails/someapp2", +# ), +# "strip-request-uri" => "/someapp2/" +# ) +# ) +# ) +# } +#} + +## chrooted webserver + external PHP +## +## $ spawn-fcgi -f /usr/bin/php-cgi -p 2000 -a 127.0.0.1 -C 8 +## +## webserver chrooted to /srv/www/ +## php running outside the chroot +# +#fastcgi.server = ( +# ".php" => (( +# "host" => "127.0.0.1", +# "port" => "2000", +# "docroot" => "/srv/www/servers/www.example.org/htdocs/" +# ))) +# +#server.chroot = "/srv/www" +#server.document-root = "/servers/wwww.example.org/htdocs/" +# + +## +####################################################################### diff --git a/Lighttpd/conf.back/lighttpd.conf b/Lighttpd/conf.back/lighttpd.conf new file mode 100644 index 0000000..aea0a40 --- /dev/null +++ b/Lighttpd/conf.back/lighttpd.conf @@ -0,0 +1,39 @@ +# See /usr/share/doc/lighttpd +# and http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions + +server.port = 80 +server.username = "http" +server.groupname = "http" +server.document-root = "/srv/http" +server.errorlog = "/var/log/lighttpd/error.log" +server.modules += ( + "mod_accesslog", + "mod_fastcgi" +) +accesslog.filename = "/var/log/lighttpd/accesslog.log" +dir-listing.activate = "enable" +index-file.names = ( "index.html" ) +mimetype.assign = ( + ".html" => "text/html", + ".txt" => "text/plain", + ".css" => "text/css", + ".js" => "application/x-javascript", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".bmp" => "image/bmp", + ".gif" => "image/gif", + ".png" => "image/png", + "" => "application/octet-stream" +) +fastcgi.debug = 1 +fastcgi.server = ( + ".php" => (( + "bin-path" => "/usr/bin/php-cgi", + "socket" => "/tmp/php.socket" + )), + #"/ctrlc" => (( + # "bin-path" => "/opt/my_service/ctrlcweb/mycgi", + # "check-local" => "disable", + # "socket" => "/tmp/ctrlcweb-mycgi.socket" + #)) +) diff --git a/Lighttpd/mycgi/ccgi.cpp b/Lighttpd/mycgi/ccgi.cpp new file mode 100644 index 0000000..11b4d65 --- /dev/null +++ b/Lighttpd/mycgi/ccgi.cpp @@ -0,0 +1,255 @@ +锘�#ifndef nullptr +#define nullptr NULL +#endif + +#include <unistd.h> +#include <time.h> +#include <errno.h> + +#include <stdlib.h> +#include <iostream> +#include <map> +#include <vector> +#include <string> +#include <sstream> +#include <algorithm> +#include <iterator> +#include <cctype> + +using namespace std; + +// http://www.fastcgi.com +#include <fcgi_stdio.h> +#include <fcgi_config.h> + + +// http://www.postgresql.org +//#include <pgsql/libpq-fe.h> +#include <libpq-fe.h> +// http://uriparser.sourceforge.net +#include <uriparser/Uri.h> + + +// https://github.com/open-source-parsers/jsoncpp +//#include <json/json.h> + + +extern char **environ; +static char **g_initial_nv = nullptr; +static size_t g_req_count = 0; + +stringstream g_log_msg; +stringstream g_http_res; + +typedef void (*url_process_func_t)(); +typedef map<string, url_process_func_t> upf_map_t; +static upf_map_t g_url_processors; + +typedef map<string, string> str_map_t; + +//=======閿欒鎻愮ず======= +static void http_res_200(const char* msg) +{ + FCGI_printf("Status: 20 OK\r\n" "Content-type: text/html\r\n" "\r\n" "%s", msg); +} +static void http_res_400() +{ + FCGI_printf("Status: 400 Bad Request\r\n" "Content-type: text/html\r\n" "\r\n"); +} +static void http_res_401() +{ + FCGI_printf("Status: 401 Unauthorized\r\n" "Content-type: text/html\r\n" "\r\n"); +} +static void http_res_404() +{ + FCGI_printf("Status: 404 Not Found\r\n" "\r\n"); +} +static void http_res_500() +{ + FCGI_printf("Status: 500 test Internal Server Error \r\n" "\r\n"); +} +static void http_res_500(int problem_code = 0) +{ + FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Problem code = %d", problem_code); +} +static void http_res_500(const char* msg) +{ + FCGI_printf("Status: 500 Internal Server Error\r\n" "Content-type: text/html\r\n" "\r\n" "Message = %s", msg); +} +//=======閿欒鎻愮ず==end===== + +size_t read_shell(const char* cmd, char* buffer, size_t buffer_size, int* exit_status = nullptr, int* exit_code = nullptr) +{ + if (cmd == nullptr) + return 0; + + FCGI_FILE* fcmd = FCGI_popen(cmd, "r"); + if (fcmd == nullptr) + return 0; + + size_t red = FCGI_fread(buffer, sizeof(char), buffer_size - 1, fcmd); + + int es = FCGI_pclose(fcmd); + + if (exit_status != nullptr) + *exit_status = es; + if (exit_code != nullptr) + *exit_code = WEXITSTATUS(es); + + return red; +} + +void run_in_bash(const char* cmd, int* exit_status = nullptr, int* exit_code = nullptr) +{ +#define BASH_WRAPPER "su -s /bin/bash -c '%s' http" + + char buffer[512]; + snprintf(buffer, sizeof(buffer) - 1, BASH_WRAPPER, cmd); + + int es = system(buffer); + + if (exit_status != nullptr) + *exit_status = es; + if (exit_code != nullptr) + *exit_code = WEXITSTATUS(es); +} + +static void print_env(const char *label, char **envp) +{ + FCGI_printf("%s:<br>\n<pre>\n", label); + for ( ; *envp != NULL; envp++) + { + FCGI_printf("%s\n", *envp); + } + FCGI_printf("</pre><p>\n"); +} + +static void hpf_echo() +{ + g_log_msg.flush(); + + char *contentLength = getenv("CONTENT_LENGTH"); + int len; + + FCGI_printf("Content-type: text/html\r\n" + "\r\n" + "<title>FastCGI echo</title>" + "<h1>FastCGI echo</h1>\n" + "Request number %d, Process ID: %d<p>\n", g_req_count, getpid()); + + if (contentLength != NULL) + len = strtol(contentLength, NULL, 10); + else + len = 0; + + if (len <= 0) + { + FCGI_printf("No data from standard input.<p>\n"); + } + else + { + int i, ch; + + FCGI_printf("Standard input:<br>\n<pre>\n"); + for (i = 0; i < len; i++) + { + if ((ch = getchar()) < 0) + { + FCGI_printf("Error: Not enough bytes received on standard input<p>\n"); + break; + } + putchar(ch); + } + FCGI_printf("\n</pre><p>\n"); + } + + print_env("Request environment", environ); + print_env("Initial environment", g_initial_nv); +} + +bool parse_query_items(str_map_t& query_items) +{ + return true; +} + +size_t get_post_content(char* buffer, size_t max_size, size_t offset_content = 0) +{ + if (buffer == NULL || max_size == 0) + return 0; + + const char* contentLength = getenv("CONTENT_LENGTH"); + size_t len = 0; + if (contentLength != NULL) + len = strtol(contentLength, NULL, 10); + + if (len == 0) + return 0; + + if (offset_content > 0) + fseek(stdin, offset_content, SEEK_SET); + + return fread(buffer, sizeof(char), min(max_size, len), stdin); +} + +const string* try_get_str_from_map(const str_map_t& str_map, const string& key, const string* default_value = nullptr) +{ + str_map_t::const_iterator iter = str_map.find(key); + if (iter == str_map.end()) + return default_value; + else + return &(iter->second); +} + + + + + +static void hpf_fishbowl_fish_count() +{ + +} + +static void hpf_fishbowl_load_v4l2grab() +{ + +} + +int main () +{ + g_initial_nv = environ; + + + + cerr << "begin accept access" << endl; + + int fcgi_accept_status; + + while ((fcgi_accept_status = FCGI_Accept()) >= 0) + { + g_req_count++; + g_log_msg.flush(); + + char* req_PATH_INFO = getenv("PATH_INFO"); + if(req_PATH_INFO == nullptr) + { + cerr << "PATH_INFO is null" << endl; + exit(EXIT_FAILURE); + } + + upf_map_t::iterator iter_upf = g_url_processors.find(req_PATH_INFO); + if (iter_upf == g_url_processors.end()) + { + http_res_404(); + } + else + { + url_process_func_t proc = iter_upf->second; + proc(); + } + } + + + cerr << "exit gracefully, fcgi_accept_status=" << fcgi_accept_status << endl; + + return 0; +} diff --git a/Lighttpd/mycgi/mycgi.cpp b/Lighttpd/mycgi/mycgi.cpp new file mode 100644 index 0000000..ba1965b --- /dev/null +++ b/Lighttpd/mycgi/mycgi.cpp @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <fcgi_stdio.h> +#include <fcgi_config.h> + + +int main(void) +{ + + int fcgi_accept_status; + + while ((fcgi_accept_status = FCGI_Accept()) >= 0) + { + + int count = 0; + printf("Content-type: text/html\r\n" + "\r\n" + "<title>CGI Hello!</title>" + + "<h1>CGI Hello!</h1>" + "Request number %d running on host <i>%s</i>\n", + ++count, getenv("SERVER_NAME")); + + } + + return 0; +} + -- Gitblit v1.8.0