CGI Program

 

CGI programs work very similar to regular programs. On entry of main(),

 

n          stdin is set to a data file which stores data from user browser.

n          stdout is set to a pipe which sends data to user browser indirectly.

 

Instead of using regular query string like "?id=xxx&p=yyy", we use the simple ISINDEX format which separates arguments by "+". The advantage of ISINDEX is that HTTP server had already parsed the arguments for us, and put them in argv[] of main(argc, argv[]). Therefore we don't need to parse the query strings, this will make things easier. The arguments are arranged as:

 

arg[1] = 's' - display web page

'u' - update settings or command

arg[2] = name of page or command.

 

The cgi program uses 30 KB memory to buffer HTML pages. It has been large enough for most CGI applications, but it may still become overflow for some authoring tools generate very complicated JavaScript to produce fancy looking. You should check the size of HTML carefully.

 

The detailed operations are best explained by codes in "app/cgi/cgi.c".

 

main() of cgi.c

// CGI Program Entry

// When starting, the HTTP server set

// stdin  (FD 0) as the input from browser ( a /tmp file handle)

// stdout (FD 1) as the output to browser  ( a pipe handle)

 

int main(int argc, char *argv[])

{   char *s,*sMethod;

    int n;

 

     // change to our working directory

     chdir("sys");

     /* Catch various termination signals. */

     signal( SIGTERM, SigTerminate );

     signal( SIGINT, SigTerminate );

     signal( SIGHUP, SigTerminate );

     // Validate CGI arguments

// We use simple ISINDEX format, 2 arguments only

    // show page        -> s + page_name

     // save / command   -> u + page_name

    if(argc!=3) HttpError("Invalid URL");

    // get HTTP method. GET or POST

     sMethod=getenv("REQUEST_METHOD");

    if(!s) HttpError("Unknown method");

    // GET method, show page

    if(strcmp(argv[1],"s")==0)

    {   // GET method only

        if(strcmp(sMethod,"GET")) HttpError("GET method only");

        // select the page we want to display

         if(strcmp(argv[2],"status")==0) ShowStatus();

         else if(strcmp(argv[2],"network")==0) ShowNetwork();

        else if(strcmp(argv[2],"io")==0) ShowIo();

        else if(strcmp(argv[2],"system")==0) ShowSystem();

    else if(strcmp(argv[2],"reboot")==0) Reboot();

        else HttpError("Invalid URL");

        // Ok, exit CGI

        exit(0);

    }

    // POST method, command or save settings

    if(strcmp(argv[1],"u")==0)

    {   // POST method only

        if(strcmp(sMethod,"POST")) HttpError("POST method only");

        s=getenv("CONTENT_LENGTH");

        if(!s) HttpError("Need data");

        m_pSize=atoi(s);

          if(m_pSize>10240) HttpError("CGI data too large");

        // Read post data into buffer

        n=fread(m_pBuf,1,m_pSize,stdin);

        if(n<=0) HttpError("CGI read error");

        // the page we want to save

    if(strcmp(argv[2],"network")==0) SaveNetwork();

         else if(strcmp(argv[2],"io")==0) SaveIo();

         else if(strcmp(argv[2],"system")==0) SaveSystem();

         else if(strcmp(argv[2],"reboot")==0) Reboot();

        else HttpError("Invalid URL");

        // Ok, exit CGI

        exit(0);

    }

    // Unknown queries

    HttpError("Invalid URL");

    return 0;

}