../../THE%20BRITISH%20EMBASSY
../../LANGUAGE%20SELECTOR

The CGI Script

Today, as even the majority of the Amiga community have begun to conquer the waste territories, and utilize the fairly unmatchable opportunities of the land called internet, the lack of javascript interpreters and java engines in the most common Amiga browsers received much greater interest and importance than ever in the past.

Until thereīs no need to do something, but to demonstrate, exhibit and present something - anything is it even from animations up to huge amounts of cross linked and anchored texts - the simple html is over all expectations. The problems will begin where presentation is less than required: if the creator behind the curtain wants some more, for example at least virtually interactive communication with the user, to have some excitement on line.

And the Creator at this point swallows a great deal of breath, and... Stands still. What the heck he can do? (Maybe that quit button will be sufficient in the upper left corner?)

He has seen things at different pages (as he can resemble to them in NetScape under Linux and Shapeshifter), like filling out queries at those ominous pages, and by pressing a Submit button, or just hitting the enter there happened marvellous things... As there are those search engines, not? Our Creator decides to make something like those, and gets up on his feets and wanders around for some advice.

Javascript - sounds the first answer from one of his bewildered fellow Creators, and an other went as far as Java at once, and suggested the Microsoft J++ in one to our excited Creator, who asks for some internet addys in order to check out the possibilities of these remarkable solutions.

Indeed, these were remarkable sites for him. Out Creator went home, and tried these URL-s, and saw nothing... At least nothing happened, except in NetScape... But that wonīt be sufficient for him, as he wanted to aim traditional Amiga users as well, not just the users of Shapeshifter or Linux.

So he returns to those fellow Creators, and asks them what to do? They were puzzled for a while, and finally they agreed in one possible solution:

cgi script...

Very good, very good indeed! Out Creator is delighted. But... What the heck is that cgi script?

Really... Whatīs that?

This marvellous CGI Script in practice is a simple program, situated in one of the web serverīs directories. If our html receives some problem to solve it collects the datas and sends the whole package to our CGI Script, and the script will return a Html page, containing the solution.

It sounds quite simple. How can we create a cgi script? At first easily. At second a little bit harder. At first easily because we can write our cgi script almost in any programming language, which can handle a standard in- and output. So we can do it easily for example both in assembler or a C compiler, of which I suggest the latter, and let me explain why. Because there is an "at second" part of the problem: the cgi script is a server side program, and thus, involving a Windows server an exe, involving a Linux one and out or an elf, and on every server itīs own executable format needed for our program to exist in. In order to convert our 68K or PPC assembly sources into such formats will mean an interestion excursion into the world of the machine language of the mentioned serversī processors, and system environments, and will mean the complete rewrite of the original: but if we do it in C, it wonīt be a great trick to get it run on an Intel, PPC or even on a Sparc processor, in almost any system environment by simply recompiling our original source with a native C compiler.

In case of the C language our only difficulty will be the task of compiling the source on a native compiler, delivering the output to itīs destination (depends from the type of the server, usually a directory called cgi-bin, scripts or so) and finally we have to make this program accessible to all users (usually the programs in that dedicated drawer automatically can be reached by the browser, but it depends on the server)

The fact is, as based on experience, that in hungary the internet service providers do not make the cgi directory accessible, and in most cases the whole directory is invisible for the webspace owner, what makes quite difficult the job of placing a script file there, and even more harder to make it accessible for all browsers. So anyhow annoying it is, we have to ask the provider directly for access over this quite important directory. (Letting the providers protect themselves, we have to tell that the cgi scripts can be quite vulnerable against hacker attacks, and in many server environments this means a serious problem. In case of tons of cgi scripts on line, uploaded absolutely uncontrolled by the general public, this can easily lead to totally unreliable service.)

Almost all of the negatives have been told by me above, and if the fact, that we have to write our cgi script in c, and that we have to face difficulties requiring time and courage when we try to place it on the server couldnīt terrorize you enough to drop the project: thereīs nothing further to frighten you.

Letīs see then, a little bit more detailed, that how can we, and a browser create and utilize our cgi script. The browser, along with the server sets many environment variables for the cgi script, and in the case described below we have to do nothing save than to read and examine these environment variables, and output a html document via the stdout - this will be what the browser will get back from the server, practically without noticing that the output generated by a cgi script, and does not come directly from a file stored on the server.

The required data used to be collected by a html tag, namely the FORM, and we will use two fields to complete our task, the TEXTFIELD to receive some information in pure text format and a SUBMIT button to send the data of the FORM html tag directly to our cgi script on the server.

The FORM tag will submit itīs contents when the submit button pressed, or the user finishes the text input in the textfield with an enter. Usually the browser uses the http-post method to send the data to the cgi-script, but we, in simplifying the process will use the default method instead. The difference will be, that the data will arrive in an environment variable called Query_String, instead of arriving to the stdin port of the cgi script. The content of the environment variable in case of "apple" written into the textfield, and presuming that the data submitted by pressing the submit button will be the follow:

textfield=alma&submit=submit

As we can see, this text can be easily tokenised, and after two strtoks we are in posession of the inputted text "alma" in the Query_String environment variable, as can be seen below.

Let us see, what environment variables do we have, set by the the server:

char *Auth_Password;
char *Auth_Type;
char *Auth_User;
char *Content_Length;
char *Content_Type;
char *Gateway_Interface;
char *HTTP_Accept;
char *HTTP_Form;
char *HTTP_Referer;
char *HTTP_User_Agent;
char *Path_Info;
char *Path_Translated;
char *Query_String;
char *Remote_Addr;
char *Remote_Host;
char *Remote_Ident;
char *Remote_User;
char *Request_Method;
char *Server_Name;
char *Server_Port;
char *Server_Protocol;
char *Server_Software;
char *Script_Name;
char *Server_Admin;

Nice list, but letīs see what these environment variables contain?

AUTH_TYPE

The level of the accessing user stored here, if the server supports passwords and the option and users are enabled. Before the user can access the cgi script an username and a password will be requested from the user, and the AUTH_TYPE will be set based on the login.

AUTH_USER

If the above mentioned option enabled, the AUTH_USER variable will contain the username of the accessing user.

AUTH_PASSWORD

If the above mentioned option enabled, the AUTH_PASSWORD variable will contain the password of the accessing user.

CONTENT_LENGTH

If we pass the data to the cgi-script via http_post method, then it will arrive to the stdin port of the script, and the length of the arrived data will be in this variable. So, CONTENT_LENGTH will contain the value of how many characters do we have to read from stdin.

CONTENT_TYPE

CONTENT_TYPE contains the MIME type of the data arrived to the stdin, for example text/html, etc.

GATEWAY_INTERFACE

The version number of the CGI handler of the server.

PATH_INFO

We can receive a path of a file from the browser. This path will be here relative to the cgi itself. It depends on the client and the cgi, what to do with this.

PATH_TRANSLATED

The same path as above, but not relative to cgi, in the PATH_TRANSLATED we receive the complete path of the file in the server.

QUERY_STRING

Here we get all parameters listed behind the cgi URL and a questionmark. When we use default submit method, the browser will send the form data here too.

REMOTE_ADDR

The IP address of the calling browser. Some people make serious efforts to obtain other peopleīs IP address, but we can have this free of charge.

REMOTE_HOST

The host name of the calling machine, on which the browser runs. If it doesnīt have one, the server will set the REMOTE_IDENT instead.

REMOTE_IDENT

The name of the user and the address of the machine will be present here.

REMOTE_USER

The name of the user can be found here.

REQUEST_METHOD

This variable contains the method, with which the browser called our cgi-script. The value should be GET, HEAD or POST, depending on the set value in the form tag.

SCRIPT_NAME

This is the name of our script. If our script called "apple.cgi", and situated in the cgi-bin drawer, the value will be - for surprise - "cgi-bin/apple.cgi"

SERVER_NAME

Here we can have the name of our server, or if it doesnīt have one, the IP number of the server.

SERVER_PORT

Here is the number of the port, through which the browser have accessed us.

SERVER_PROTOCOL

The protocoll and itīs version number used to establish the connection.

SERVER_SOFTWARE

The name and version number of the server and operating system software.

HTTP_ACCEPT

A list of the acceptable MIME types ofthe browser.

HTTP_USER_AGENT

The type, name and version number of the calling browser.

As we can see, the informations at our disposal are numerous and some of them very valuable, and unreachable for the simple user. We can use and abuse these datas: a great part of server hijacks made through cgi scripts - but as we will only use our Query_String, and in addition indirectly, the hacker must be an extremely skilled one, who can use our cgi-script for such purposes.

We can place our varuables into a single structure, in a way like this:

struct EnvironmentVariables
{
}

if we place the long list above between the brackets. And then if we create a variable with this structure:

struct EnvironmentVariables EV;

Then we can use the elements via the getenv command. Along the getenv we have no other thing to do, than repeating the variable name in capitals. For example we can get our Query_String variable in the following way:

EV.Query_String = getenv("QUERY_STRING");

After doing so we can (almost) tokenize it in the following way, supposing that we have a textfield and a submit button in our form, and so the second token will be the content of our textfield:

EV.Query_String = strtok(EV.Query_String, "=&");
EV.Query_String = strtok(NULL, "=&");

As we can see, at first we slice our variable by the = and & characters into tokens, and after the first call we will have the first token "textfield". Calling the strtok with a null it gives back the second token, and the value of our variable, supposing that the entered text into the textfield was "apple", will be - for surprise - "apple".

Now we can compile the source, and wonīt get a warn, but: compiling it with gcc under a linux environment, we will get back segment violation error, if the strtok have to tokenise an empty textfield. Sad but true, we have to check it before every strtok. (And wonder who the f*** invented the C language?) Of course we have to make TWO checks, one for the case when the user presses the submit button, and one for the case when the user presses enter (as then we wonīt receive the state of the submit button) Letīs see the source (quite ugly) in the case of submit button pressed: (the received data is "textfield=&submit=submit")

char *duplatoken = {"=&"};
char *myptr;
char *myptr2;

myptr2 = myptr;
myptr = strstr (EV.Query_String,duplatoken);
if (myptr2 == myptr)
{
//here comes our program
}
else
{
//here comes a message to the user, that he entered an empty string
}

And now let us check the second case, when the user tries a simple enter, to confuse us. (received data is "textfield=")

a = strlen(EV.Query_String);
if (EV.Query_String[a-1]==61) //61 is =
{
//here comes our program
}
else
{
//here comes a message to the user, that the textfield is empty
}

We should use this two together. Of course, to make our life a little bit more difficult, the browser converts the inputed text, for example all space characters morph into "+", and all extra characters (accents,%,= etc.) will became a three characters long thingie, beginning with a "%", and followsed by the hexadecimal value of the original character (for example "á" will became "%e1"). Prepare to handle this!

So, weīve at least received out variables, we have the value of the textfield in our variable - and we have only two more things to do. At first we have to examine the value of the textfield, and we have to generate an answer html, depending on the examined value.

As we cannot give back anything, we have to tell to the browser that he will get a html back, what the browser will readily display. The browser will get what we send to it via the stdout - and now we will prepare the browser to receive our html data with the following three lines:

printf("Content-type: text/html\n"); printf("\n"); printf("<!DOCTYPE HTML PUBLIC \"-//W30//DTD W3 HTML 4.0//EN'\">\n");

As we can possibly deduct, we send him the MIME type of the following data. Now we can do anything, as an example we will return the value of the read variable:

printf("<html>\n");
printf("<head>\n");
printf("</head>\n");
printf("<title>Ez egy cgi script altal generalt html file\n");
printf("</title>\n");
printf("<body>\n");
printf("Az EV.Query_String valtozo erteke: %s\n",EV.Query_String);
printf("</body>\n");
printf("</html>\n");

So, in this way we have a working cgi script. We have to do nothing else
save compiling the source into a suitable format, placing it to the good
place on the server, and we have to place a form tag into our html, with a
textfield and a submit button, and we have to give our cgi´s url as the form
tag´s link. This will look like this:

<form action="HERE_COMES_THE_URL_OF_THE_CGI" name="">
<input type="text" name="textfield" value="">
<input type="submit" name="submit" value="submit">
</form>

And we are ready, we can test our cgi script at last. All my best wishes to
the new CGI creators around...


Emeric SH

 

     
MAGYAR ENGLISH MAGYAR ENGLISH