The abbreviation "CGI" stands for Common Gateway Interface. It describes a mechanism how
web servers can delegate the generation of web pages to a stand-alone application (an executable file).
Such applications are commonly known as CGI scripts, but they are not required to be scripts,
they can be written in any programming language.
With CGI the web site designer can provide dynamic content to the user. Websites are generated on-the-fly,
so the user can interact with the server and the underlying software, for example data bases.
Sayed with other words: A CGI program can generate any kind of data that is downloaded to and displayed by
the web browser. Usually the dynamically generated data will be a html file, but it can also be any other type
of data, like a picture or a pdf file.
The Website Hit Counter
I wanted to track how many users are visiting my website and I wanted to collect some statistics about the
load of my MyCPU webserver. In the past I had to use the services of other ISPs: I included a link to an image on
an other website, and when the image was loaded the other webserver tracked the access so I got some statistics.
But I wanted my little MyCPU server to work stand-alone, so I had to get rid of the external services.
My idea was to extend the MyCPU server by some CGI like features, allowing me to generate my own small counter-images
on-the-fly when the website is loaded. And so I implemented the CGI interface into my webserver code and wrote the
program "counter.cgi" that provides the counting service.
The counter plugin "counter.cgi" is written in "C" and is stored in the new directory
8:/bin/cgi. It is referenced from within the configuration file 8:/etc/httpservcfg. If you whish to add the counting
service to your MyCPU webserver, simply download and install the latest MyCPU software distribution, edit the
httpservcfg - file and add the line "
+ 8:/bin/cgi/counter.cgi" to it.
The counter image that is displayed is configurable and can have one of these styles:
The first style, style number 0, is the "analog" style. It is similar to the old mechanical counters.
The second style (it has the number 1) is the "digital" style where you can configure the colors. Same with
the third style (ID number 2) which is the "mini"-counter. Examples:
If you want to add such a counter to your website, you have to place a "<img>"-tag somewhere in you
website. The ID-number of the counter, the style of the counter and the color is configured by optional parameters
that are added to the URL.
For a simple "analog" counter add the tag
to your html source code. If you want to have the very little blue/white counter on your web site, you have to
insert the code
<img src="counter.cgi?style=2&fgcol=ffff00&bgcol=0000ff"> into
your html side.
The table lists the options that are supported:
Selects the counter image style. Style numbers 0, 1 and 2 are supported. If this option is not set, the counter
has style 0 by default.
MyCPU can manage 10 different counters. If you want to use more than one counter on your website,
add this option to define the ID-number of the counter (the values 0 to 9 are valid for this option).
If this option is not set, the counter 0 is used by default. Note: All counters do access-filtering,
that means, a counter is not triggered twice when it is loaded from the same source IP address within
30 minutes. The counter number 9 does not do this filtering, it is incremented on every access.
ctr=9 (selects counter number 9)
These options set the color scheme of the counters with style 1 and 2. The color is coded as a three-byte
hexadecimal RGB value. fgcol = foreground color, bgcol = background color, bgcol2 = background color of the
inactive segments of counter style 1. Example:
Defines the width (number of digits) of the counter. Example: len=10 defines a very long counter.
The counter is not counted up when this option is set. This option does not take a parameter value.
This option can be used to forward the http referrer to the counter cgi. To do this you will need a little bit
of java script. This option should be last and it should be started with to & signs. Example:
When this option is set the counter.cgi creates no bitmap file but a html file that shows detailed
counter statistics. Example:
counter.cgi?print loads a common statistics page that contains links
to detailed statistics for each counter.
Counter statistics are saved to the file
8:/etc/webcounters.txt. The file contains an editable and a
fixed section. Please do not change any data in the fixed section, because this will result in losing all counter
history. The counter statistics are saved at least one time per day to the file, so not too much data is lost in the
case the webserver crashes (which happens really seldom :-))
Click here to see the counter statistics of this website
Use Any Program to Generate Dynamic Content
With "exec.cgi" you can use any program to generate dynamic web content. When a request
for exec.cgi is made by the webbrowser, exec.cgi calls in turn a user-defined program whose stdout-stream
is captured and forwarded to the browser. If you are a lazy guy how don't like to learn a new programming
language like "C", you can also use the good old Basic to provide dynamic content. The syntax of exec.cgi is
simple. For example "
http://192.168.1.1/exec.cgi?x=ver" executes the shell command "ver"
and displays the installed OS version in the webbrowser.
But what is with user input? In most cases users are entering some data into a web form that is then processed
by a server side application. MyCPU's exec.cgi knows three ways to provide input data to your application. The first
way is sending it to the std-input stream. The second is to provide "command line parameters" that are
appended to the application call. For example, if you want to call the "mem" command with the parameters
"-t -s" (="mem -t -s" on the shell prompt), you could send the CGI-request
http://192.168.1.1/exec.cgi?x=mem&p=-t -s" to the server. And the third way is to use dedicated
environment variables to pass up to 9 values to the application. From within a basic program you can access this
variables through the "
The table shows all parameters supported by exec.cgi:
Mandatory. Sets the program that shall be executed on the server. For example "
will execute your basic-program "myprogram.bas" on the server.
This parameter can be used to insert some null-bytes at the beginning of the stdin-stream. Some programs that clear
the input buffer at start up may require this parameter to work properly. For example add "n=2" to
insert two null-bytes into the stream.
Forward plain text from the URI to the stdin stream of the executed program. For example
t=hello world" will put the words "hello" and "world" into the
input stream, so that you could use a "INPUT A$" from within a Basic program to read the string
"hello world" into the variable A$. But note: The Basic interpreter echoes back the input data to the
stdout stream. So you have to do some tricks to avoid that your input data is looped back to the generated website.
(A trick is to place the echoed data in a hidden section in the generated html file, eg. by using the html
Same like the parameter "t", but replaces all commas (",") through a carriage return (CR) character.
Use this parameter to forward binary data to your application program. Binary data is appended in hexadecimal notation
to this parameter, so that for example "
h=327E5A00C3" will put the bytes 32 7E 5A 00 and C3
in the program's input stream.
1 to 9
The numbers 1 to 9 are placeholders for environment variables with the same name. The environment variables can
then be read from within the application program. For example the URI
http://192.168.1.1/exec.cgi?x=myprog.bas&1=MyCPU&2=rules" will set the environment variables
1 and 2 before calling the program myprog.bas. When the Basic program contains the line
print env$("1");env$("2")" you will see the text "MyCPUrules"
in the generated website.
If you want to use exec.cgi to generate dynamic web content, you must enable exec.cgi
in the webserver configuration file 8:/etc/httpserv.cfg. Please add the line "
to the file, so that exec.cgi gets loaded when the webserver is started. The file must be extended by the names of the
programs you want be able to execute from the web interface. For example, if you want to allow exec.cgi to execute the
programs "mem" and "ver", you must add the following line to the configuration file:
+ 8:/bin/cgi/exec.cgi 8:/bin/mem ver" (of course without the quotation marks)
exec.cgi supports different MIME format types for the generated output stream.
The MIME type is set with a control string at the beginning of the generated stream. These control-strings (MIME types)
are currently supported by the MyCPU webserver:
If no MIME type is set by your program, the webserver tries to set the type automatically. For example you don't need
to set the MIME type if you are providing plain text or html data.
Here is an example of a small basic program that collects system information and generates a html page. Click the
link exec.cgi?x=sysinfo.bas to see the generated page:
120 print"<html><head><title>MyCPU System Info</title></head><body>"
130 print"<h2>System Uptime</h2><pre>"
150 print"</pre><br><hr><h2>Last System Errors</h2><pre>"
170 print"</pre><br><hr><h2>Loaded Modules</h2><pre>"
180 shell"mem -a"
190 print"</pre><br><hr><h2>Network Statistics</h2><pre>"
200 shell"netstat -t"
210 print"</pre><br><hr><h2>Network Configuration</h2><pre>"
The C-Program API
If the provided CGI handlers
exec.cgi do not satisfy your needs,
you can write your own CGI handler program in 'C'. The table below shows the relevant functions that are
const char* httpfile,
This function is called from the main()-entry of your C-program. It registers the CGI callback handler function
and starts the CGI service. "httpfile" is the name of the export (eg. "counter.cgi") and
"cgihandler" is a pointer to the handler function. The handler function gets called every time a
webbrowser requests your CGI file. All further work is performed in the callback handler function:
You can write up to 16kb output data to the stdout stream by using
printf() and friends.
Stops the CGI service. You should call this function from an exit-handler that is registered through
a call to
atexit(). See countercgi.c and execcgi.c for details.
Optional: Registers a callback function that is called one time per second when the http-server is idle.
This can be used to do some background operation.
const char *paramname);
Get a string-parameter from GET-request-line (URI). Parameters are separated by '&'-signs and values
are assigned by a '='-signs. For example, if your CGI handler is called with the URI "
myprog.cgi?day=monday&week=25", a call of
will return a pointer to the value "25".
Set the MIME type of the generated data. These types are defined: MIME_PLAINTEXT, MIME_HTML, MIME_BMP,
MIME_GIF, MIME_JPEG, MIME_PNG, MIME_PDF, MIME_ZIP, MIME_RAR, MIME_TGZ, MIME_TAR, MIME_GZ
int addr, char value);
Writes a byte into the CGI output buffer. Note that the output buffer has a size of approx. 16kb.
char cgi_bufPeek(int addr);
Reads back a byte from the CGI output buffer.
Please see the example programs
execcgi.c for more details. These
files are included in the latest MyCPU software package.