Navigation

3.4 Komplexbeispiele

3.4.1 CGI-Programmierung

Immer stärker wird die Nutzung des WEB zum bestimmenden Merkmal der Rechnernutzung. In diesem Abschnitt soll kurz veranschaulicht werden, wie der Aufruf eines C-Programms als sogenanntes CGI-Programm aus einem WEB-Browser aufgegrufen werden kann.

Das folgende Beispiel ist ein einfacher Taschenrechner, der als WEB-Seite aufgerufen werden kann. In das Formular können die Werte op1, op und op2 eingegeben werden. Mit der Anweisung:
<form method="get" action=".../rechner.cgi">
erfolgt der Aufruf eines sogenannten CGI-Programmes rechner.cgi, dem über die Environment-Variable QUERY_STRING die eingegebenen Werte übergeben werden (bei method="post" über stdin).

BEISPIELE/CGI/rechner.html: 

<HTML>
<HEAD>
 <TITLE>Rechner</TITLE>
     <LINK REL=STYLESHEET TYPE="text/css" HREF="/tu/style.css">

</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#FF6666" ALINK="#CC6600" VLINK="#CC0000">
<FONT FACE="Arial,Helvetica">
<center>
<h1>"Supercomputer"</h1>
</center>
<p>
<form method="get" action="http://www-usercgi.tu-chemnitz.de/urz/kurse/unterlagen/C/BEISPIELE/CGI/rechner.cgi">
<center>
<p>
&nbsp;
<p>
    <input type="text" size="15" name="op1" value="0.0">
    <select name="op">
	<option value="1">+ (Addition)
	<option value="2">- (Subtraktion)
	<option value="3">* (Multiplikation)
	<option value="4">/ (Division)
	</select>
    <input type="text" size="15" name="op2" value="0.0">
<p>
<input type=reset value="Formular zurücksetzen">
&nbsp;
<input type=submit value="Ergebnis anzeigen">
</center>
</form>
</FONT>
</BODY>
</HTML>

Im HTML-Formular wird die Eingabe über verschiedene input bzw. select Anweisungen gesteuert. Der eigentliche Aufruf des CGI-Programms erfolgt bei submit. Hier wird QUERY_STRING gesetzt und in folgender Form als Environment bereitgestellt:
QUERY_STRING="op1=11.22&op=3&op2=33.44"
Das C-Programm liest mittels Bibliotheksfunktion getenv() diesen Wert ein, berechnet das Ergebnis und erzeugt in stdout eine HTML-Seite, die zur Anzeige des Ergebnisses dient.

BEISPIELE/CGI/rechner_cgi.c: 

/********************************************************************/
/* Beispiel fur ein CGI-Programm in der Sprache C                   */
/********************************************************************/
/* CGI = Common Gateway Interface                                   */
/********************************************************************/
/* CGI-Programme werden auf einem Web-Server ausgeführt             */
/* sie erzeugen dynamische Webseiten - oft auf Grundlage von Daten, */
/* die über ein  Web-Formular bereitgestellt werden                 */
/* ein CGI-Programm schreibt "normales" HTML in die Standardausgabe */
/********************************************************************/
/* ein CGI-Programm muss auf Webserver Plattform übersetzt werden   */
/* der Name des ausführbaren File muss auf  .cgi enden              */
/*   cc  rechner_cgi.c -o rechner.cgi                               */
/********************************************************************/
/* bei method="get" in der Formulardefinition werden die Daten des  */
/*                  ausgefüllten Formulars in der Umgebungsvariable */
/*                  QUERY_STRING bereitgestellt ( "post" in stdin)  */
/* Beispiel:        QUERY_STRING="9999.9999&op=9&op2=9999.999"      */
/********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

/************************************/
/* Funktion error() zeigt Fehler an */
/************************************/

int fehler=0;
void error(fm)
char *fm;
{
     printf("<center><h2><p>Fehler: %s\n</h2></center>", fm);
     fehler=1;
}

/*******************************************************************/
/* Funktion print_header() gibt die "Kopfsätze" der HTML-Seite aus */
/*******************************************************************/

char header0[]="Content-type: text/html\n\n";
char header1[]="<HTML>\n<HEAD>\n<TITLE>CGI Rechner</TITLE></HEAD>\n";
char header2[]="<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\"> \n";
char header3[]="<FONT FACE=\"Arial,Helvetica\"> \n";
char header4[]="<center><h1>\"Supercomputer\"</h1></center><p> \n";
void print_header()
{
  printf(header0);
  printf(header1);
  printf(header2);
  printf(header3);
  printf(header4);
}

/*******************************************************************/
/* Funktion print_footer() gibt "Schlusssätze"  der HTML-Seite aus */
/*******************************************************************/

char footer1[] = "</FONT>\n </BODY>\n </HTML>\n";
void print_footer()
{
  printf(footer1);
}

/********************************************************************/
/* Funktion syntax() prüft, ob ein String fz nur Bestandteile einer */
/* Gleitkommazahl enthält                                           */
/* j ist die Nr. des Operanden für evtl. Fehlermeldungen            */
/********************************************************************/

void syntax(fz,j)
char *fz;
int j;
{
  int i;
  char fehlstr[50];

  i=0;
  while(fz[i] != '\0') {
    if(fz[i]>='0' && fz[i]<='9' || fz[i]=='.' || fz[i]=='-')
     i++;
    else {
     sprintf(fehlstr,"%d. Operand %s ist keine Gleitkommazahl!",j,fz);
     error(fehlstr);
     return;
    }
  }
}

main ()
{
   int x;
   double op1, op2, erg;
   char zkop1[512], zkop2[512], query[512], *poi, rechenop, opz;

   print_header();

   if(getenv("QUERY_STRING") == NULL) {
     /* das sollte eigentlich nicht vorkommen */
     error("QUERY_STRING nicht definiert");
     print_footer();
     exit(1);
   }
   strncpy(query,getenv("QUERY_STRING"),512);
   if(query[0]=='\0') {
     error("Im rufenden Dokument bei Formulardefinition method!=get");
     print_footer();
     exit(1);
   }
   if((poi=strstr(query,"op1=")) != NULL) {
     strcpy(zkop1,poi+4); /* zkop1=9999.99999&op=9&op2=99999.99999 */
     x=0;
     while(zkop1[x] != '&' && zkop1[x] != '\0') x++;
     zkop1[x]='\0';
     syntax(zkop1,1);
     op1=atof(zkop1);
   } else {
     /* wenn CGI als URL oder aus falschem Formular gerufen wird */
     error("op1 nicht angegeben");
   }
   if((poi=strstr(query,"op2=")) != NULL) {
     strcpy(zkop2,poi+4);
     x=0;
     while(zkop2[x] != '&' && zkop2[x] != '\0') x++;
     zkop2[x]='\0';
     syntax(zkop2,2);
     op2=atof(zkop2);
   } else {
     error("op2 nicht angegeben");
   }
   if((poi=strstr(query,"op=")) != NULL) {
     rechenop=*(poi+3);
   } else {
     error("op nicht angegeben");
   }
   switch (rechenop) {
     case '1': erg=op1+op2;
               opz='+';
               break;
     case '2': erg=op1-op2;
               opz='-';
               break;
     case '3': erg=op1*op2;
               opz='*';
               break;
     case '4': if(op2 == 0) error("Division durch Null");
               erg=op1/op2;
               opz='/';
               break;
     default: error("Falsches Operationszeichen");
   }
   if(fehler != 0) {
       print_footer();
       exit(1);
   }
   printf("<center>\n<h2>");
   printf("%s %c %s = %f\n", zkop1, opz, zkop2, erg);
   printf("</h2></center>\n");
   print_footer();
}

siehe auch Navigation