Site hosted by Angelfire.com: Build your free website today!

When using files with CGI scripts.


* The first thing to know about CGI scripts is.
They must be fast. You can see why?
If you have a 100 people, all pressing the send button at the same time. Well.

*In most operating system, today. When you execute a program. You are not executing that program.
You are executing an instance, copy, of that program.
That is why you can have more then one copy of a program running.

But, when you write to a pacific file. You have to open it.
When using a CGI script to write to a file.

For writing to a file. For reading a file. Why not jest copy it to the temp file? Because some one might change the original file.
At the same time you are. And the original file. Wood only reflect the last entree.
Backup you file. Use the CGI script to do this. Before you change the file.

Linux has a C++ function call flock(). Windows does not. So how do we lock a file?
One way is to create a temp file. Jest before opening the original file. And deleting it jest after close the original.
You CGI script will not open the original file. If the temp file exist.

*Decoding a Form string.
There is 2 methods to send output to the CGI script. POST and GET.
The output is a single string. And both are the same. Hear is an example.
Raw string POST or GET == cat=Anime&scat=Comidy&url=www.anime&urlname=Anime+comity
If the form string is the same. Then why is there 2 methods?

*POST and GET.
GET.
Add to output, of the form, to the URL.
https://www.google.com/search?client=firefox-b-1-d&q=car+2024
Every thing after &q= is the form output (string). car+2024
Limited to 2048 charters. Not including the URL.
Is used by all the search engines.
Can be read by anyone. If thay know how.
POST.
Post is more secure then GET.
No limit on data length. Other then server memory.
All ways check the length of a form string. Before using it.
Use POST when sending sensitive info.

GET.
You retrieve the form string using the system function getenv().
It returns a char pointer. You can get the string length with strlen(char *).
char *data = getenv("QUERY_STRING"); size_t length = strlen(data);
POST.
You retrieve the string length with char *lenstr = getenv("CONTENT_LENGTH");
Convert the pointer to a long with sscanf(lenstr,"%ld",&len); long len;
And get the string with fgets(TheString, len+1, stdin); char *TheString;
The form string is stored in a memory spaced called stdin.

The HTML forms is on the index.html file.
Copy this to c:\apache24\htdocs\index.html Overwriting index.html.
 index.html code 


This is a simple CGI script. That return witch method, GET or POST, you are using.
Also I rename my CGI scripts. filename.exe to filename.cgi The server will execute then fine.
 PostReturn.cpp 


This display the Raw string from the index.html web page.
 PostData.cpp 


Returns the Raw HTML string. Decoded string. The entrees.
And Write (appends) the entrees to a file (output.txt).
This display the Raw string from the index.html web page.
 PostReturnData.cpp 


Next we will retrieve the contents of the text file, output.txt. That in the cgi-bin directory.
And add a ID number the display it to the HTML page.
 PostReturnData.cpp 

Remember I sad you need to lock the data file before opening? And close it jest after closing the data file.
We are going to talk about that.

We will change this function. Adding a timeout function.
Lets look at the function cfile(char *filename) in PostReturnData.cpp.

///Create a file. And append values to it.
void cfile(char *filename) {
ofstream myfile;

   myfile.open (filename,std::ios_base::app);
   for(int x=0;x<rolls;x++) {
      myfile << buffer2[x];
      myfile << "\n";
   }

myfile.close();
}
The fist thing we need is a timeout timer.
Is a timeout time using on a file. To test it.

The first thing is to add 2 headers. At the top of the Cpp file.
#include <ctime> ///Time functions, and #include <sys/stat.h> ///stat struct.
Then add the timeout and file exist functions. To PostReturnData.cpp.
/// /////////////////////////
///Timmer.
void timmer() {

   ///trigger; The bigger the number the slower.
   int msec = 0, trigger = 10000; //ms.
   ///The clock() function returns the
   /// processor time since the program started.
   ///clock_t == clock tick counts. Stored in before.
   clock_t before = clock();

   ///loop.
   do {
      ///Get current ticks - before ticks.
      clock_t difference = clock() - before;
      ///msec, in this case, is about a second.
      msec = difference * 10000 / CLOCKS_PER_SEC;
   ///When the msec (1 second) == trigger. exit loop.
   }while(msec < trigger);
}
/// /////////////////////////
///Does the filelock file exist? 0.134s
inline int fileexist(char *name) {
///stat is a struct that hold file info.
struct stat buffer;

///Return 0 if exist.
///The stat() function obtain
/// information about the named file.
return(stat(name,&buffer));
}
/// /////////////////////////

Add the timmer() and fileexist(char *name) jest before the cfile(char *filename) function. New we going to change the cfile(char *filename) function.
///Create a file. And append values to it.
bool cfile(char *filename) {
ofstream myfile;
int exist = 0; ///Does exist.

	///Loop 4 times.
   for(int x=0;x<4;x++) {
      ///If not 0 file does not exist. break;
      if(fileexist((char *)"Timer.lock")!=0) {
         exist = 1; break;
      }
      timmer();
   }

   ///If file stell exist, exit main() (presses).
   if(exist == 0) {
      error((char *)"ERROR: File timed out.");
      return false;
   }

   ///Create lock file.
   ofstream lockfile;
   lockfile.open("C:\\Apache24\\cgi-bin\\Timer.lock");
   lockfile.close();

   myfile.open (filename,std::ios_base::app);
   for(int x=0;x<rolls;x++) {
      myfile << buffer2[x];
      myfile << "\n";
   }

   ///Close output file.
   myfile.close();
   ///Delete the lock file.
   if(remove("C:\\Apache24\\cgi-bin\\Timer.lock") != 0){
      error((char *)"Unable to delete the lockfile!"); return false;
   }

return true;
}

In the main() function. Change cfile((char *)"output.txt"); to
int exist = 0; ///Does exist.
exist = cfile((char *)"output.txt");
if(exist == 0) { return 1; }

Compile PostReturnData.cpp and rename to PostReturnData.cgi.
Copy to c:\apache24\cgi-bin. Start apache24. localhost in the web browser.
Fill out the form under "And Write (appends) the entrees to a file (output.txt). "
Press the POST button. You shod get the file contents as a return.
New in the cgi-bin directory. Create a text file called "Timer.lock".
Press the POST button. You shod get an error, after 5 seconds. ERROR = ERROR: File timed out.

New lets tolk about Method GET.


When creating a GET form. Use "<br><input type="submit">"
Do not add name="Whatever" or value="Whatever".
Becouse it will send that too. And you will need to remove it from the getenv("QUERY_STRING");.

AddGet Subtract, Multiply, Divide (2 floting) or Add (2 to 4 floting).
AddGet.cpp

StringGet Copy the 4 values into a 2D array.
StringGet.cpp

Why copy 4 values into a 2D array?
So you can use them to filter your search.
if(strcmp("John Doe",str[0]) == 0) { //do whatever. }
But there a batter way to search data files.
CGI scripts and xBase.

< >