There are two main reasons for yacgi:
... Important: if you write your own main() function, your program will not link properly. Your own code should begin with cgiMain(). The library provides main() for you.
... This function takes advantage of cgiFormCheckboxMultiple(), which is used to identify one or more selected checkboxes with the same name. This function performs identically to cgiFormSelectMultiple(). That is, <SELECT> tags with the MULTIPLE attribute are handled just like a group of several checkboxes with the same name.
... and so on.
example: "A person works in an enterprise."
Picture 1.
In general, an access function is a function which maps one object into the powerset of another (the set of all subset). While defining a relation one gives the key and value object types involved, and one defines the access function and gives information about its cardinality. When the cardinal of an access function is unique then it is a function. When the cardinal of an access function is multiple then it is a multiple-valued function.
For the CGI programming (about the CGI standard, see the CGI documentation at NCSA.) we can use a very simple model:
Please see the file license for the details of the Basic License and Commercial License, including ordering information for the Commercial License.
Opening Relation
This code opens the relation.
#include <stdio.h> #include <stdlib.h> #include "yacgi.h" main(int argc, char *argv[]) { CGI *cgi; printf("Content-type: text/html%c%c",10,10); /*----------------------------------------------------------- * Opening Relation *-----------------------------------------------------------*/ cgi = cgiOpen(); if(!cgi) { printf("<H3>%s</H3>%c",cgiStateMsg(),10); exit(1); }
Closing Relation
You should close the relation before exit the program.
/*------------------------------------------------------ * Closing Relation. *------------------------------------------------------*/ cgiClose(cgi); }
Scanning Relation
You can use traversing or scanning the relation, accessing each
stored pair of names-values in turn to perform some test or
action.
#include <stdio.h> #include <stdlib.h> #include "yacgi.h" main(int argc, char *argv[]) { CGI *cgi; int more; char *string; printf("Content-type: text/html%c%c",10,10); /*----------------------------------------------------------- * Opening Relation *-----------------------------------------------------------*/ cgi = cgiOpen(); if(!cgi) { printf("<H3>%s</H3>%c",cgiStateMsg(),10); exit(1); } /*----------------------------------------------------------- * Scanning Relation *-----------------------------------------------------------*/ printf("<CENTER><H2>Scanning Name-Value Relation</H2></CENTER>"); printf("You submitted the following name/value pairs:<p>%c",10); printf("<ul>%c",10); more= cgiFirst(cgi); while(more) { printf("<li> <code>%s = %s</code>%c",cgiName(cgi), cgiValue(cgi),10); more = cgiNext(cgi); } printf("</ul>%c",10); /*------------------------------------------------------ * Closing Relation. *------------------------------------------------------*/ cgiClose(cgi); }
Evaluating Relation
We can "navigate" from objects to objects using binary relation. To do this, we use cgiValueFirst and cgiValueNext functions. For instance, we have a Name "sex" and want to know value of sex. The code is:
#include <stdio.h> #include <stdlib.h> #include "yacgi.h" main(int argc, char *argv[]) { CGI *cgi; int more; char *string; printf("Content-type: text/html%c%c",10,10); /*----------------------------------------------------------- * Opening Relation *-----------------------------------------------------------*/ cgi = cgiOpen(); if(!cgi) { printf("<H3>%s</H3>%c",cgiStateMsg(),10); exit(1); } /*----------------------------------------------------------- * Evaluating Relation *-----------------------------------------------------------*/ printf("<CENTER><H2>Evaluating Name-Value Relation</H2></CENTER>"); printf("<p><b>%s</b><br>%c","First Name",10); string = cgiValueFirst(cgi, "First_Name"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Last Name",10); string = cgiValueFirst(cgi, "Last_Name"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Date of Birth",10); string = cgiValueFirst(cgi, "D_O_B"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Sex",10); string = cgiValueFirst(cgi, "Sex"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Degree",10); string = cgiValueFirst(cgi, "Degree"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Current Occupation",10); string = cgiValueFirst(cgi, "Occupation"); if(string) printf("<code>%s</code><br>%c",string,10); printf("<p><b>%s</b><br>%c","Duties",10); string = cgiValueFirst(cgi, "Duties"); if(string) printf("<code>%s</code><br>%c",string,10); /*---------------------------------------------------------- * Let us now look at multiple relations. Assume we want the * skills of the person. * We write: *---------------------------------------------------------*/ printf("<p><b>%s</b><br>%c","Skills",10); string = cgiValueFirst(cgi, "Skills"); while(string) { printf("<code>%s</code><br>%c",string,10); string = cgiValueNext(cgi, "Skills"); } /*------------------------------------------------------ * Closing Relation. *------------------------------------------------------*/ cgiClose(cgi); }
Advanced Features
Provides string, integer, floating-point, and safe string without shell metacharacters functions to retrieve form data.
#include <stdio.h> #include <stdlib.h> #include "yacgi.h" main(int argc, char *argv[]) { CGI *cgi; int more; char *string; int flag; long i; double r; char c[31]; printf("Content-type: text/html%c%c",10,10); /*----------------------------------------------------------- * Opening Relation *-----------------------------------------------------------*/ cgi = cgiOpen(); if(!cgi) { printf("<H3>%s</H3>%c",cgiStateMsg(),10); exit(1); } /*------------------------------------------------------------- * Advanced Features: Input String, Integer, Real, * Safe String *-----------------------------------------------------------*/ printf("<CENTER><H2>Advanced Features</H2></CENTER>"); printf("<p><b>%s</b><br>%c","String",10); flag = cgiValueString(cgi, "String", c, 30); if(flag == CGI_OK || CGI_VAL_TRUNCATED ) printf("<code>%s</code><br>%c",c,10); else printf("<code>%s</code><br>%c",cgiStateMsg(),10); printf("<p><b>%s</b><br>%c","Integer",10); flag = cgiValueInteger(cgi, "Integer", &i, 1); if(flag == CGI_OK ) printf("<code>%ld</code><br>%c",i,10); else printf("<code>%s</code><br>%c",cgiStateMsg(),10); printf("<p><b>%s</b><br>%c","Real",10); flag = cgiValueReal(cgi, "Real", &r, 1); if(flag == CGI_OK ) printf("<code>%lf</code><br>%c",r,10); else printf("<code>%s</code><br>%c",cgiStateMsg(),10); printf("<p><b>%s</b><br>%c","SafeString",10); string = cgiValueFirst(cgi, "SafeString"); if(string) printf("<code>%s</code><br>%c",cgiSafeStr(string),10); /*------------------------------------------------------ * Closing Relation. *------------------------------------------------------*/ cgiClose(cgi); return(0); }
The sample application 'yacsampl.c' is provided as part of the yacgi distribution. This CGI program accepts input submitted by the form yacsampl.html.
IMPORTANT: after compiling yacgi, you will need to place it in a location on your server system which is designated by your server administrator as an appropriate location for CGI scripts. Also, the URL of the action of the sample form in yacsampl.html must be changed to correctly indicate the location of yacsampl on your web server.
CGI Environment ADT available via functions:
void cgiClose(CGI *cgi);
Closes the relation.
Evaluate functions:
char *cgiValueFirst(CGI *cgi, char *Name);
Evaluates the first Value in the relation by the supplied
Name. Returns the first Value in the
relation that has a given Name. Null is returned if no pair
meets the condition. In the event of error it returns 0.
char *cgiValueNext(CGI *cgi, char *Name);
Evaluates the next Value in the relation by the supplied Name.
Returns the next Value in the relation
that has a given Name. Null is returned if no pair meets the
condition. In the event of error it returns 0.
Iterate functions:
int cgiFirst(CGI *cgi);
Moves the current position to the first stored pair. On
successful completion, cgiFirst returns 1. In the event of
error it returns 0.
int cgiNext(CGI *cgi);
Moves the current position to the next stored pair. On
successful completion, cgiNext returns 1. In the event of
error it returns 0.
char *cgiName(CGI *cgi);
Returns a Name of the current pair. If
there is an error or if the relation is empty it returns 0.
char *cgiValue(CGI *cgi);
Returns a Value of the current pair. If
there is an error or if the relation is empty it returns 0.
Advanced features:
char *cgiSafeValue(CGI *cgi, char *Name);
Evaluates the first Value in the relation by the supplied
Name.
Returns the first Value in the
relation that has a given Name and ESCAPES the shell metacharacters.
Null is returned if no pair meets the condition.
In the event of error it returns 0.
int cgiValueString(CGI *cgi, char *name,
char *result, int max);
Evaluates the first Value in the relation by the supplied
Name.
The string will be copied into the buffer specified by result,
up to but not exceeding max-1 bytes.
The function returns CGI_OK if the Value was successfully retrieved.
If the string was retrieved but was truncated to fit the buffer it
returns CGI_VAL_TRUNCATED,
CGI_VAL_EMPTY if the string was retrieved but was empty, and
CGI_VAL_NOTFOUND if no such Name was submitted.
int cgiValueInteger(CGI *cgi,
char *name, long *result, long defval);
Evaluates the first Value in the relation by the supplied
Name.
The value pointed to by result will be set to the value submitted.
The function returns CGI_OKif the Value was
successfully retrieved,
CGI_VAL_EMPTYif the Value submitted is an empty string,
CGI_VAL_BADTYPE if the Value submitted is not an integer,
and CGI_VAL_NOTFOUND if no such Name
was submitted.
In the last three cases, the Value pointed to by result
is set to the specified default.
int cgiValueReal(CGI *cgi, char *name,
double *result, double defval);
Evaluates the first Value in the relation by the supplied
Name.
The value pointed to by result will be set to the value submitted.
The function returns CGI_OKif the Value was
successfully retrieved,
CGI_VAL_EMPTYif the Value submitted is an empty string,
CGI_VAL_BADTYPE if the Value submitted is not a real number,
and CGI_VAL_NOTFOUND if no such Name
was submitted.
In the last three cases, the Value pointed to by result
is set to the specified default.
CGI_OK | The function successfully performed |
CGI_MEMORY | Out-of-memory error |
CGI_CONTENTTYPE | MIME content type error |
CGI_REQUESTMETHOD | Request metod error |
CGI_IO | I/O error |
CGI_VAL_TRUNCATED | Value was cut short |
CGI_VAL_INVALID | Value was not a legal type |
CGI_VAL_EMPTY | Value contained no data |
CGI_VAL_NOTFOUND | No value was submitted |
CGI_LASTERROR |
State of Relation is accessed via the following operations:
void cgiStateClear();
Resets state of Name-Value Relation to CGI_OK
int cgiStateGet();
Returns current state of Name-Value Relation
int cgiStateSet(int val);
Resets state of Name-Value Relation to the given value
char *cgiStateMsg();
Returns state of Name-Value Relation string
The CGI standard specifies a number of environment variables which are set by the server.
Instead of calling getenv() you can use cgiEnvGet function that always returns valid C strings (they are never null, although they may point to an empty string).
Copyright © 1997 Andrew Girow. All Rights Reserved.