/****************************************************************************
*
* (C) 1999 by BECK IPC GmbH
*
*  BECK IPC GmbH
*  Garbenheimerstr. 38
*  D-35578 Wetzlar
*
*  Phone : (49)-6441-905-240
*  Fax   : (49)-6441-905-245
*
* ---------------------------------------------------------------------------
* Module      : Example1.c
*
* Function    :
        This program demonstrates the usage of the implemented
				CGI-Interface of IPC@CHIP in a dos program.
				The programmer should use this program as an example
				for building own cgi functions.
                                For a better understanding the programmer should first
                                read the html documentation of the CGI API.


				Compiler     : Microsoft Visual C V1.52
				Projectfile  : example1.mak
				Memorymodel  : Large


				Compiler     : Borland C 3.0
				Projectfile  : example1.prj
				Memorymodel  : Large



				Important for the usage of Microsoft C-Compiler:

				1. Use as struct member byte aligment: 1Byte !!!!!
				or #pragma pack(1) and #pragma check_stack( off )

				2. Cgi functions must be declared as the following:
				void far _saveregs _loadds _pascal Example1_Func(rpCgiPtr CgiRequest);


				3. Microsoft C compiler will not accept the follwing statements
				   from  the main function:

				   inregs.x.dx   = FP_SEG(&example);
				   inregs.x.si   = FP_OFF(&example);

				   because example is a structure, we changed it:

				   //declare a pointer of type CGI_ENTRY
				   CGI_Entry  * cgiptr;



				   cgiptr =  &example;
				   inregs.h.ah   = CGI_INSTALL;
				   inregs.x.dx   = FP_SEG(cgiptr);
				   inregs.x.si   = FP_OFF(cgiptr);




				At this example, we placed a error directive define,
				if memory model large is not used.


				We install a cgi function, which
				produces a dynamic htmlpage in the memory.
				This page has the name "example1". The name of the
				installed cgi function is "example_func1".
				The expected http method is "get".

				If a browserrequest e.g. http://192.168.205.4/example1
				comes in, the web server calls this function.
				This function produces a html pages, which contains
				the browser request data from the given parameter
				rpCGiPtr

				At the mainloop of our program, we increment a counter
				once per second. The program runs 2 minutes


				During runtime of the program, the page "example1"
				can be loaded from a browser.


				After two minutes the program ends.
				A browserrequest after the end of the program
				returns "Object not found, ......"


				Important:
				At the end of the program we must remove the installed
				cgi function from webservers CGI table.



* Author        : Bartat
* Date          : 09.11.99
* Version       : V1.00
* ---------------------------------------------------------------------------
* History       :
*
*  Vx.yy        Author  Changes
*
*  V1.00          mb    Create
*  V1.01          mb    add cgi func declaration for Microsoft C
*  V1.02          mb    change declaration type of cgi funcs to pascal declaration
						SC12 bios version V065
*  V1.03          mb    Replaced "" with \" at html strings

*****************************************************************************/


/****************************************************************************/
//includes
/****************************************************************************/
#include <DOS.H>
#include <STDIO.H>
#include <STRING.H>    


/****************************************************************************/
/* Compiler dependent defines, Microsoft C V152 */
/****************************************************************************/


#ifdef _MSC_VER

  //set structure member assignment to 1Byte !!!!
  #pragma pack(1)
  #pragma check_stack( off )	
  
  #ifndef _M_I86LM                    
    #error Must use LARGE memory model
  #endif   

#endif /* _MSC_VER */



/****************************************************************************/
//API includes 
/****************************************************************************/


//needed for sleep call
#include "TCPIPAPI.H"
//cgi types, constants, ...
#include "CGI.H"
/*************************************************************************/
//constants 
/*************************************************************************/
//needed interrupt vectors
#define TCPIPVECT     0xAC
#define CGIVECT       0xAB


#define MAIN_LOOPS    120L   /* our program run MAIN_LOOPS seconds*/
/****************************************************************************/
//needed registerstructs for CGI interrupt calls
/****************************************************************************/
union  REGS  inregs;
union  REGS  outregs;
struct SREGS segregs;

/***************************************************************************
  the name of the page for the browserrequest
  e.g. http://192.168.200.5/example1
****************************************************************************/
char * HtmlPageName     = "REQUEST";
/***************************************************************************
//our cgi entry webserver
 ***************************************************************************/
CGI_Entry   example;

CGI_Entry  * cgiptr;

unsigned long MainLoopCounter = 0L;

/***************************************************************************
Predefine head and tail of our page
***************************************************************************/
char * PageHead = "<HTML><HEAD><TITLE>IPC@CHIP CGI example1</TITLE></HEAD>"
				  "<BODY BGCOLOR=\"#A0A0A0\">"
				  "<IMG SRC=\"beck.gif\" ALIGN=\"RIGHT\" ALT=\"BECK\">"
				  "<BR><BR>"
				  "<CENTER>"
				  "<H1>IPC@CHIP CGI example1</H1>"
				  "<HR size=0>"
				  "</CENTER>"
				  "<FONT FACE=\"Courier\" SIZE=+2>"
				  "<BR>Browser request: <BR>"
				  "</FONT>"
				  "<FONT FACE=\"Courier\" SIZE=+1>";



char * PageEnd = "</FONT>"
				 "<HR size=0>"
				 "<p align=center><SMALL><EM>&copy BECK IPC GmbH, 1999</EM>"
				 "</BODY>"
				 "</HTML>";

/***************************************************************************
we store at the cgi function our page in this buffer
***************************************************************************/

char HtmlPage[1024];

/****************************************************************************
	CGI function, the webserver executes this function, if a
	browser request e.g. http://192.168.200.8/example1 comes in,
	We build at this function a new html page in memory,
	which shows the important request fields of the the main
	parameter struct rpCGIPtr



****************************************************************************/

//Microsoft Visual C
#ifdef _MSC_VER
//void far _saveregs _loadds Example1_Func(rpCgiPtr CgiRequest)
void far _pascal _saveregs _loadds Example1_Func(rpCgiPtr CgiRequest)
#else
//void huge  Example1_Func(rpCgiPtr CgiRequest)
void huge _pascal Example1_Func(rpCgiPtr CgiRequest)
#endif

{

	 char tmpbuffer[180];

   /**********************************/
   //building the page
   /**********************************/
   
   //insert the head of the page
   strcpy(HtmlPage,PageHead);


   //append the given request arguments

   sprintf(tmpbuffer,"<BR>Method     : %02d<BR>",CgiRequest->fHttpRequest);
   strcat(HtmlPage,tmpbuffer);

   sprintf(tmpbuffer,"<BR>Url        :    %s<BR>",CgiRequest->fPathPtr);
   strcat(HtmlPage,tmpbuffer);                             

   sprintf(tmpbuffer,"<BR>Host       :   %s<BR>",CgiRequest->fHostPtr);
   strcat(HtmlPage,tmpbuffer);


	 sprintf(tmpbuffer,"<BR>Referer    :   %s<BR>",CgiRequest->fRefererPtr);
	 strcat(HtmlPage,tmpbuffer);

	 sprintf(tmpbuffer,"<BR>User Agent :   %s<BR>",CgiRequest->fAgentPtr);
	 strcat(HtmlPage,tmpbuffer);

	 sprintf(tmpbuffer,"<BR>Content    :   %s<BR>",CgiRequest->fLanguagePtr);
	 strcat(HtmlPage,tmpbuffer);

	 sprintf(tmpbuffer,"<BR>User       :   %s<BR>",CgiRequest->fUserNamePtr);
	 strcat(HtmlPage,tmpbuffer);

	 sprintf(tmpbuffer,"<BR>Password   :   %s<BR>",CgiRequest->fPasswordPtr);
	 strcat(HtmlPage,tmpbuffer);



	 if(strlen(CgiRequest->fArgumentBufferPtr))
	 {
	 sprintf(tmpbuffer,"<BR>Arguments:  %s<BR>",CgiRequest->fArgumentBufferPtr);
	 }
	 else
	 {
	 strcpy(tmpbuffer,"<BR>No arguments<BR>");
	 }
	 strcat(HtmlPage,tmpbuffer);


   //append the predefined tail
   strcat(HtmlPage,PageEnd);

   /**********************************/
   //give it to the webserver
   /**********************************/

   CgiRequest->fHttpResponse         = CgiHttpOk;       //HTTP 200 OK
   CgiRequest->fDataType             = CGIDataTypeHtml; //text/html
   
   
   CgiRequest->fResponseBufferPtr    = HtmlPage;
   CgiRequest->fResponseBufferLength = strlen(HtmlPage);

   
}
/****************************************************************************/

int main(void)
{


   printf("\r\nStarting CGI example1\r\n");
   #ifdef _MSC_VER
   printf("Microsoft C\r\n");
   #endif

   /*******************************************************************/
   //install example cgi function
   /*****************************************************************/

   //init CGI_entry example;
   example.PathPtr    = HtmlPageName;    //name of the page
   example.method     = CgiHttpGet;      //method
   example.CgiFuncPtr = Example1_Func;   //function

   cgiptr =  &example;

   // We need this helpptr because the Microsoft compiler
   // will not accept the following:
   // inregs.x.dx   = FP_SEG(&example);
   // inregs.x.si   = FP_OFF(&example);

   inregs.h.ah   = CGI_INSTALL;
   inregs.x.dx   = FP_SEG(cgiptr);
   inregs.x.si   = FP_OFF(cgiptr);

   int86(CGIVECT,&inregs,&outregs);

   if(outregs.x.dx == (unsigned int)CGI_ERROR)
   {

	  printf("\r\nInstalling CGI function %s failed --> exit program\r\n",example.PathPtr);
	  return 0;
   }

   /******************************************************************
    Now the webserver knows everything about the function and
    is able to execute it, if a browserrequest
      e.g. http://192.168.200.4/example1
    comes in
   *****************************************************************/




   /*******************************************************************/
   //Main loop: Increment a counter
   //
   /*******************************************************************/
   while(MainLoopCounter < MAIN_LOOPS)
   {

       //increcment the counter for our dynamic html page
       MainLoopCounter++;

       //sleep a second
       inregs.h.ah = API_SLEEP;
       inregs.x.bx = 1000; //milliseconds
       int86(TCPIPVECT,&inregs,&outregs);
   }

   /****************************************/
   //Important: remove example cgi function
   /****************************************/

   inregs.h.ah   = CGI_REMOVE;
   inregs.x.dx   = FP_SEG(example.PathPtr);
   inregs.x.si   = FP_OFF(example.PathPtr);
   int86(CGIVECT,&inregs,&outregs);

   if(outregs.x.dx == (unsigned int)CGI_ERROR)
   {

	  printf("\r\nRemoving %s failed\r\n",example.PathPtr);
	  return 0;
   }


   printf("\r\nExit program\r\n");

   return 0;
}
/*************************************************************************/
//end example1.c
/*************************************************************************/
